Macro hygiene for macro m(ex...)

I have two macros defined as follows:

macro m1(ex)
    :($ex)
end    

macro m2(ex...)
    :($ex)
end  

And the results of macro expansions are:

julia> @macroexpand @m1 a, b
:((Main.a, Main.b))

julia> @macroexpand @m2 a, b
(:((a, b)),)

My question is why the symbols :a and :b are not qualified with module name in the case of @m2 unlike to @m1?

Thank you!

Not sure but your output isn’t equivalent either. The second one makes a tuple with another tuple inside, because a, b is parsed as one tuple arg in both macro invocations.

I know their outputs have to be different. In m2 , args is slurping the one argument (a, b) into an one-element tuple, which is expected. My question is why m2, symbols are not being hygiened by macro expansion.

Ah now I get it, you’re inserting a Tuple into the AST in @m2, and this doesn’t go through macro hygiene because it is not an Expr or Symbol. You can embed anything you want in the AST in case you didn’t know, but it’s uncommon to do so.

julia> dump(@macroexpand @m1 a, b)
Expr
  head: Symbol tuple
  args: Array{Any}((2,))
    1: GlobalRef
      mod: Module Main
      name: Symbol a
    2: GlobalRef
      mod: Module Main
      name: Symbol b

julia> dump(@macroexpand @m2 a, b)
Tuple{Expr}
  1: Expr
    head: Symbol tuple
    args: Array{Any}((2,))
      1: Symbol a
      2: Symbol b
1 Like

Oh, I didn’t know about that. Thank you so much!

Ah I remembered one example which does this, the regex string macro. It inserts a Regex object into the AST so that it is already compiled at compile time.

julia> dump(@macroexpand r"abc")
Regex
  pattern: String "abc"
  compile_options: UInt32 0x040a0002
  match_options: UInt32 0x40000000
  regex: Ptr{Nothing} @0x00007fb0a0ce5ff0
1 Like