消除 Julia 元编程中各种引用机制的歧义

Disambiguate the various quoting mechanisms in Julia metaprogramming

有人可以清楚地列出 Julia 中可用于元编程的各种引用机制,并用一个最小的例子来说明每一种机制吗?

以便清楚在什么情况下使用哪个...

据我所知有:

这个列表全面吗?我是否遗漏了任何替代表示?

:... 是默认的引用机制。它解析一个表达式和 returns AST。

:x == Symbol("x")

:(x + y) == Expr(:call, :+, :x, :y)

:(x; y; z) == Expr(:block, :x, :y, :z)

eval(:<expr>) 应该 return 与 <expr> 相同(假设 <expr> 是当前全局 space 中的有效表达式)

eval(:(1 + 2)) == 1 + 2

eval(:(let x=1; x + 1 end)) == let x=1; x + 1 end

quote ... end 等同于 :(begin ... end)


Expr(:quote, x)用于表示引号中的引号。

Expr(:quote, :(x + y)) == :(:(x + y))

Expr(:quote, Expr(:$, :x)) == :(:($x))

QuoteNode(x) 类似于 Expr(:quote, x) 但它防止插值。

eval(Expr(:quote, Expr(:$, 1))) == 1

eval(QuoteNode(Expr(:$, 1))) == Expr(:$, 1)

这是一个使用了所有这些的宏:

macro quoted(expression)
    quote
        println("received expression: :(", $(QuoteNode(expression)), ")")
        $(Expr(:quote, expression))
    end
end

用法:

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

编辑Meta.quot(x)确实和Expr(:quote, x)一样。它没有记录,也没有在任何地方提到,但它是对 Base (https://github.com/JuliaLang/julia/pull/1755) 导出的函数的有意识的补充,我还没有看到任何弃用它的计划,所以你可以使用它。