The problem is that you are overwriting the function called "get":

julia> get == f1 == f2
true

An anonymous function will accomplish the goal:

  make_expr(x) = begin body = x*2; quote () -> $body end; end

Or you could "gensym" the function name.
(I should also point out that using a macro for this sort of thing will
give better performance than eval, and is probably more idiomatic)

On Tue, Dec 16, 2014 at 9:15 PM, Constantin Berzan <[email protected]>
wrote:

> Hello,
>
> I ran into some strange behavior with a piece of code that takes in Julia
> expressions, transforms them, and then evaluates them.  Here is a minimal
> example:
>
> let
>>     function make_expr(x)
>>         body = x * 2
>>         quote
>>             function get()
>>                 $body
>>             end
>>         end
>>     end
>>     ex1 = make_expr(1)
>>     f1 = eval(ex1)
>>     ex2 = make_expr(2)
>>     f2 = eval(ex2)
>>     println(ex1)
>>     println(ex2)
>>     println(code_lowered(f1, ()))
>>     println(code_lowered(f2, ()))
>>     println(f1())
>>     println(f2())
>> end
>
>
> And here is the output I get when running this with Julia 0.3.2
> (8227746b95):
>
> begin
>>     function get()
>>         2
>>     end
>> end
>> begin
>>     function get()
>>         4
>>     end
>> end
>> {:($(Expr(:lambda, {}, {{},{},{}}, :(begin
>>         return 4
>>     end))))}
>> {:($(Expr(:lambda, {}, {{},{},{}}, :(begin
>>         return 4
>>     end))))}
>> 4
>> 4
>
>
> As you can see, inside the expressions we have the values 2 and 4, but
> inside the compiled functions we have the values 4 and 4.
>
> I've never seen expressions disagreeing with their eval-ed form before.
> Is this a bug?  Or am I misunderstanding something about scope?
>
> I tried using a let statement for "body = x * 2", but that did not change
> anything.
>
> Thanks,
> Constantin
>

Reply via email to