The Julia compiler is not really designed for this level of dynamicity. It
is generally recommended to avoid eval if there is some simpler way to
structure your program. In this case (function parameters) you might be
able to create types to hold your parameters, and pass those around.
Reading through code in base can be instructive:  there are ~23 uses of
"eval" in base, and nearly all of those are in the REPL and loading code
where such use really can't be avoided.

(this approach would also preclude the new "precompilation" feature, which
can significantly reduce loading time for many packages)

On Sun, Oct 11, 2015 at 6:46 PM, Andrew Keller <andrew.keller...@gmail.com>
wrote:

> Thank you for the helpful advice. In this particular case, I can indeed
> just do what you suggest and call @eval at the top level in my module in a
> for loop. It would be useful to know explicitly why it is considered poor
> form to define types inside a function; I don't think it is clear from the
> follow-up link, though I found it helpful for other reasons. I'm using the
> function for my own internal purposes and not exporting it.
>
> Elsewhere in my code, I define a function to create other *functions*—not
> types—based on a few parameters. My module has several includes, and in
> each included file it makes sense to create functions based on some
> parameters in a Dict. So in this case, I like using the function to create
> other functions, because I can just call it in each included file. Is this
> considered bad style? If so, what is an alternative that is comparably
> concise?
>
> On Sunday, October 11, 2015 at 3:04:25 PM UTC-7, Isaiah wrote:
>>
>> You are calling `symbol` on an object, which results in a fully-qualified
>> name when called inside a module:
>>
>> julia> module Foo
>>        abstract a
>>        f() = symbol(a)
>>        end
>>
>> julia> Foo.f()
>>
>> symbol("Foo.a")
>>
>>
>> (or try adding `@show superSymb` inside your function)
>>
>> Creating a symbol from a type instance here isn't really necessary
>> because you can splice in `$supertype` directly. (see the "Metaprogramming"
>> section of the manual)
>>
>> Having said that: calling a function to create a type is not
>> recommended/idiomatic. Instead, you could call `@eval` at the top level in
>> your module (possibly in a for loop). There are a handful of examples of
>> this in base, for example in "linalg/triangular.jl".
>>
>>
>>
>>
>> On Sun, Oct 11, 2015 at 12:01 PM, Andrew Keller <andrew.k...@gmail.com>
>> wrote:
>>
>>> I'm using Julia 0.4.0 on Mac OS X 10.10.5. I'd like to put some code
>>> into a module, but I'm having some trouble with namespaces. The following
>>> fails (`UndefVarError: test.a not defined`) when enclosed inside `module
>>> test`. When outside the module, e.g. pasted into the REPL, the code works
>>> fine. Could someone point me to relevant reading material or explain what
>>> is going on?  It seems I can avoid the problem by putting the string "a" in
>>> the dictionary instead of the abstract type, but I want to know why I am
>>> unable to do things as written. Thank you for your patience as I am new to
>>> the language.
>>>
>>> module test
>>>
>>> abstract a
>>>
>>> dict = Dict("key" => a)
>>>
>>> function createType(typeName::ASCIIString,supertype::DataType)
>>>
>>> typeSymb = symbol(typeName)
>>> superSymb = symbol(supertype)
>>> @eval immutable ($typeSymb){T} <: $superSymb
>>>
>>> num::Float64
>>>
>>> end
>>>
>>> end
>>>
>>> createType("b",dict["key"])
>>>
>>> end
>>>
>>
>>

Reply via email to