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
>

Reply via email to