Sorry to revive this old thread, but I am trying to understand macros, so please bear with me:
When I try to use this example , replacing expr by Expr so the macro becomes: macro dict(syms...) Expr(:dict, { :($(Expr(:quote,s))=>$(esc(s))) for s in syms }) end When I now ask for julia> r = @dict(a,b) I get ERROR: syntax: malformed expression Also this version: macro dict(syms...) Expr(:dict, { :($(string(s))=>$(esc(s))) for s in syms }) end doesn't work for me either; it gives the same error. Could someone please explain to me why the expression returned by the macro is malformed? This is on Julia 0.3 Windows 8 64bit. Thanks very much! Ivo Op donderdag 7 februari 2013 21:39:27 UTC+1 schreef René Donner: > > Thanks a lot, the trick with writing out the expressions first is great to > know! > > May I propose adding this somewhere at the end of the manual section on > macros? I think it nicely gives a very valuable bit of practical advice, > before one ventures out into the cold world of trial and error ;-) > > > Just for reference, I modified the macro slightly to use the actual names > instead of the symbols as the keys: > > macro dict(syms...) > expr(:dict, { :($(string(s))=>$(esc(s))) for s in syms }) > end > > > Thanks again, > > Rene > > > > > Am 07.02.2013 um 21:25 schrieb Stefan Karpinski <ste...@karpinski.org > <javascript:>>: > > > This does it: > > > > macro dict(syms...) > > expr(:dict, { :($(expr(:quote,s))=>$(esc(s))) for s in syms }) > > end > > > > The approach I used, which is generally effective for writing macros is > to create an example of the expression I want the macro to construct and > then write code to build that: > > > > julia> ex = :([:a => "hello", :b => "world"]) > > :($(expr(:dict, :(:a=>"hello"), :(:b=>"world")))) > > > > julia> ex.head > > :dict > > > > julia> ex.args > > 2-element Any Array: > > :(:a=>"hello") > > :(:b=>"world") > > > > So I want an Expr object whose head is :dict and whose args is an array > of expression of the form :(:sym => value). The tricky bits are: > > • Wrapping s in expr(:quote,s) so that it ends up in the final > AST as an expression for a symbol rather than splicing the symbol directly > in since that would be as if you'd written the variable rather than the > symbol for it. > > • Wrapping the s in esc(s) so that it is evaluated in the macro > caller's context, not the macro definition context. Note that this isn't a > concern for expr(:quote,s) because symbols are the same in any context. > > Hope that helps. > > > > > > On Thu, Feb 7, 2013 at 3:02 PM, René Donner <li...@donner.at > <javascript:>> wrote: > > Hi, > > > > I would like to write a macro which easily allows to contruct Dict's > using the actual variables' names, like so: > > > > a = "hello" > > b = "world" > > r = @dict a b # r == {"a"=>"hello","b"=>"world"} > > > > The following macro does the job, but how could I get rid of the "eval" > (which I read one is not supposed to use inside a macro, rather just to > yield an AST). > > > > macro dict(a...) > > quote > > local r = Dict{Any,Any}() > > for i in 1:length($a) > > r[string(($a)[i])]=eval(($a)[i]) > > end > > r > > end > > end > > > > > > Thanks a lot for any advice! > > > > Rene > > > > > > > >