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
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.