Could someone lay out clearly the various quoting mechanisms available for metaprogramming in Julia, and illustrate each one with a minimal example?
So that it is clear which to use in which situation...
As far as I can see there is:
:(someExpr; maybeMore)
quote; ...expressions... end;
which is almost the same as the above only with line numbers for debug purposesExpr(:quote, x)
which (according to @totalverb) is equivalent to Meta.quot(x)
Is this list comprehensive? Am I missing out any alternate representations?
:...
is the default quoting mechanism. It parses an expression and returns the AST.
:x == Symbol("x")
:(x + y) == Expr(:call, :+, :x, :y)
:(x; y; z) == Expr(:block, :x, :y, :z)
eval(:<expr>)
should return the same as just <expr>
(assuming <expr>
is a valid expression in the current global space)
eval(:(1 + 2)) == 1 + 2
eval(:(let x=1; x + 1 end)) == let x=1; x + 1 end
quote ... end
is the same as :(begin ... end)
Expr(:quote, x)
is used to represent quotes within quotes.
Expr(:quote, :(x + y)) == :(:(x + y))
Expr(:quote, Expr(:$, :x)) == :(:($x))
QuoteNode(x)
is similar to Expr(:quote, x)
but it prevents interpolation.
eval(Expr(:quote, Expr(:$, 1))) == 1
eval(QuoteNode(Expr(:$, 1))) == Expr(:$, 1)
Here's a macro using all of them:
macro quoted(expression)
quote
println("received expression: :(", $(QuoteNode(expression)), ")")
$(Expr(:quote, expression))
end
end
Usage:
julia> x = 1
1
julia> @quoted $x + 1
received expression: :($(Expr(:$, :x)) + 1)
:(1 + 1)
julia> @quoted :(x + 1)
received expression: :($(Expr(:quote, :(x + 1))))
:($(Expr(:quote, :(x + 1))))
edit: Meta.quot(x)
is indeed the same as Expr(:quote, x)
. It's undocumented and isn't mentioned anywhere, but it was a conscious addition to the functions exported by Base
(https://github.com/JuliaLang/julia/pull/1755) and I haven't seen any plans to deprecate it, so you can use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With