On Sun, Sep 25, 2016 at 10:11 AM, Marius Millea <mariusmil...@gmail.com> wrote: > Ahh nice, thanks. Your macrocall suggestions reads cleanly too, I think it'd > look something like this: > > julia> macro macrocall(mac,args...) > Expr(:macrocall,esc(mac),map(esc,args)...) > end > @macrocall (macro with 1 method) > > julia> @macrocall idmacro 1+2 > 3 > > > What's the problem with local variables you mention though? I can't think of > where this wouldn't work.
macrocall resolve the macro to be called in current **module** (i.e. current global scope) since it runs in the parser and has no idea about any local bindings. This means that you might as well just assign the value to a global starts with `@` and call it directly with normal macro syntax. > > > On Sunday, September 25, 2016 at 2:08:46 PM UTC+2, Yichao Yu wrote: >> >> On Sun, Sep 25, 2016 at 7:25 AM, Marius Millea <marius...@gmail.com> >> wrote: >> > I can store a macro to a variable (let use the identity macro "id" as an >> > example), >> > >> > julia> idmacro = macro id(ex) >> > :($(esc(ex))) >> > end >> > @id (macro with 1 method) >> > >> > >> > How can I use this macro now? I can *almost* do it by hand by passing an >> > expression as an argument and eval'ing the result, but it doesn't work >> > because there's esc's left, >> >> Assuming this is just for understanding how macros are implemented, >> you can just construct a microcall expression >> >> julia> idmacro = macro id(ex) >> esc(ex) >> end >> @id (macro with 1 method) >> >> julia> idmacro(:(1 + 2)) >> :($(Expr(:escape, :(1 + 2)))) >> >> julia> eval(Expr(:macrocall, :idmacro, :(1 + 2))) >> 3 >> >> This is unlikely what you want to do in real code. >> >> Side notes, >> >> As shown above, you can just do `esc(ex)`, `:($foo)` is equivalent to >> `foo` >> >> You can also use a variable name starts with `@` since that's the >> syntax that triggers the parsing to a macrocall expression. >> >> julia> eval(:($(Symbol("@idmacro")) = idmacro)) >> @id (macro with 1 method) >> >> julia> @idmacro 1 + 2 >> 3 >> >> julia> Meta.show_sexpr(:(@idmacro 1 + 2)) >> (:macrocall, Symbol("@idmacro"), (:call, :+, 1, 2)) >> >> >> You can do this transformation with a macro too (i.e. make @macrocall >> idmacro 1 + 2 construct a macrocall expression) but it's not really >> useful since you can't do this for a local variable, which is also why >> I said don't do this in real code. >> >> > >> > julia> @id 1+2 >> > 3 >> > >> > >> > julia> idmacro(:(1+2)) >> > :($(Expr(:escape, :(1 + 2)))) >> > >> > >> > julia> eval(idmacro(:(1+2))) >> > ERROR: syntax: unhandled expr (escape (call + 1 2)) >> > in eval(::Module, ::Any) at ./boot.jl:234 >> > in eval(::Any) at ./boot.jl:233 >> > >> > >> > >> > Does Julia provide a way to use such macros stored in variables? Thanks!