On Wed, May 4, 2016 at 12:09 PM, Gustavo Goretkin
<[email protected]> wrote:
> I have this macro
>
> """given symbols, produce a dictionary of symbol=>value"""
> macro symbol_dict(symbols...)
> Dict([__x=>@eval($(__x)) for __x in symbols])
> end
Do not use `@eval` in macro, it happens in the wrong scope and in this
case, the wrong time.
macro symbol_dict(symbols...)
:(Dict($([:($(QuoteNode(sym)) => $(esc(sym))) for sym in symbols]...)))
end
>
> that works like this
> julia> (x,y) = (30,50)
> (30,50)
>
> julia> @symbol_dict(x,y)
> Dict{Any,Any} with 2 entries:
> :y => 50
> :x => 30
>
> I have another macro
>
> macro value_dict(decision_variables...)
> rebindings = [:($(_x) = value($(_x))) for _x in decision_variables]
> # print(rebindings)
> @eval let $(rebindings...)
Again, don't use `@eval`.
> println($rebindings)
> println("x", x)
> println("y", y)
> D = @symbol_dict($(decision_variables...))
> end
> end
When using a macro, you want to generate the expression but not evaluate.
iiuc what you want is sth like
macro value_dict(vars...)
:(let $([:($(esc(var)) = value($(esc(var)))) for var in vars]...)
@symbol_dict($([esc(var) for var in vars]...))
end)
end
>
> which behaves like
>
> julia> @value_dict(x,y)
> [:(x = value(x)),:(y = value(y))]
> x60
> y100
> Dict{Any,Any} with 2 entries:
> :y => 50
> :x => 30
>
> I expected that the dictionary have the "rebound" values. What am I
> misunderstanding? I could stand to re-read many sections of the manual...
>
> I see that if I do
> julia> @value_dict(x)
> [:(x = value(x))]
> x60
> y50
> Dict{Any,Any} with 1 entry:
> :x => 30
>
> It prints out `y50`, which I expect. `y` wasn't rebounded in the `let`
> clause, so its original value is visible to the print call. To the macro
> invocation, however, only the original values of x and y are visible.
>
> This is Julia Version 0.4.4-pre+1.
> Thanks!
> Gustavo
>