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!

Reply via email to