What is the deal with macros that do not return expressions?

106 wyświetleń
Przejdź do pierwszej nieodczytanej wiadomości

Lyndon White

nieprzeczytany,
1 paź 2016, 05:26:501.10.2016
do julia-users
I was generally under the impression that a macro always had the return a `Expr`
and that doing otherwise would make the compiler yell at me.

Apparently I was wrong, at least about the second part:
https://github.com/ChrisRackauckas/ParallelDataTransfer.jl/issues/3



macro ex_timestwo
(x)
   
:($(esc(x))*2)
end



@ex_timestwo(4)
8

macroexpand
(:(@ex_timestwo(4)))
:(4 * 2)

@ex_timestwo(a)
LoadError: UndefVarError: a not defined


macroexpand
(:(@ex_timestwo(a)))
:(a * 2)



?

VS: not returning an expression, and just doing a thing:

macro n_timestwo(x)
 x
*2
end


@n_timestwo(4)
8


macroexpand
(:(@n_timestwo(4)))
8


@n_timestwo(a)
LoadError: MethodError: no method matching *(::Symbol, ::Int64)


macroexpand
(:(@n_timestwo(a)))
:($(Expr(:error, MethodError(*,(:a,2)))))




Is this a feature?
Or is it just undefined behavior?

Yichao Yu

nieprzeczytany,
1 paź 2016, 08:13:401.10.2016
do Julia Users
You can return whatever you want. If it is one of the AST node
type[1], it'll be used as a expression. Otherwise, it'll be used as a
literal value. This is because not all quotes/AST nodes are Expr
(`typeof(:(1))`) and you can use `QuoteNde`[2] if you want to embed an
arbitrary object literal.

[1] http://julia.readthedocs.io/en/latest/devdocs/ast/
[2] https://github.com/JuliaLang/julia/pull/18660

Greg Plowman

nieprzeczytany,
1 paź 2016, 08:31:551.10.2016
do julia-users
In your two examples, note the difference when the macro argument is multiplied by 2.

@ex_timestwo happens at runtime
@n_timestwo happens at macro expansion time

a = 6
@ex_timestwo(a)
will return 12 as expected,

whereas:
a = 6
@n_timestwo(a)
will still result in error because at macro expansion time, it is trying to evaluate (:a) * 2
Odpowiedz wszystkim
Odpowiedz autorowi
Przekaż
Nowe wiadomości: 0