So normally when nesting an expression into an expression, it seems like it doesn’t matter if the latter is written as a quoted :( ___ )
or an Expr(:quote, ___ )
. There’s a difference when the former is written as a quote or an Expr
, but the nested expressions eval
to the same inner expression.
julia> @macroexpand x + 1
:(x + 1)
julia> :( :(x+1) ) == Expr(:quote, :(x+1) )
true
julia> eval( :( :(x+1) ) )
:(x + 1)
julia> :( :(x+1) ) == :( Expr(:call, :+, :x, 1) )
false
julia> eval( :( Expr(:call, :+, :x, 1) ) )
:(x + 1)
But things seem to change when the symbol $
is involved. First, there’s no way to quote the expression Expr(:$, :x)
parsed from the source code $x
, which kind of makes sense because $x
is a syntax error. Second, putting Expr(:$, :x)
in either a quoted :( ___ )
or an Expr(:quote, ___ )
now makes a difference. The former is more like a nested expression because it evals
to the inner Expr(:$, :x)
. The latter is almost what happens in @eval $x
(and why I started on this train of thought). Third, the latter is somehow equivalent to nesting a different expression :($x)
in a :( ___ )
. I can’t really make sense of this.
julia> x = 3
3
julia> @macroexpand $x
:($(Expr(:$, :x)))
julia> Expr(:$, :x) # REPL print is redundant
:($(Expr(:$, :x)))
julia> :( Expr(:$, :x) ) == Expr(:quote, Expr(:$, :x) ) # ?!
false
julia> eval( :( Expr(:$, :x) ) )
:($(Expr(:$, :x)))
julia> eval( Expr(:quote, Expr(:$, :x) ) )
3
julia> Expr(:quote, Expr(:$, :x) ) == :( :($x) ) # ?!
true