keorn
keorn

Reputation: 75

How to evaluate Julia expression defining and calling a macro?

I am generating some code that is later being evaluated. Even though the generated code is correct and evaluating it line by line does not cause issues, it fails to be correctly evaluated as a whole.

eval(quote
  macro m() "return" end
  @m()
end)

Returns: ERROR: LoadError: UndefVarError: @m not defined

eval(quote macro m() "return" end end)
eval(@m())

Returns: "return"

Upvotes: 5

Views: 635

Answers (1)

StefanKarpinski
StefanKarpinski

Reputation: 33290

Macro expansion is done before evaluation, so when macro expansion occurs in this code the definition of the macro in the first expression in the block happens too late to affect the expansion of the second expression in the block. There is one special case which does what you want: the :toplevel expression type. This is automatically used for top-level global expressions in modules but you can manually construct expressions of this type like this:

ex = Expr(:toplevel,
    :(macro m() "return" end),
    :(@m())
)

And sure enough, this does what you want:

julia> eval(ex)
"return"

Since Julia doesn't have locally scoped macros, this macro definition has to take place in global scope already so presumably this should work anywhere that the original macro would have worked—i.e. a macro definition should be valid in all the same places that a top-level compound expression is valid.

Upvotes: 6

Related Questions