Clojure - 引用混乱

ano*_*ous 7 lisp macros clojure

对不起那个模糊的标题:)

我是宏的新手,我很难理解这两个陈述之间的区别:

`(+ 1 2 ~(+ 2 3)) ; => (clojure.core/+ 1 2 5)
'(+ 1 2 ~(+ 2 3)) ; => (+ 1 2 (clojure.core/unquote (+ 2 3)))
Run Code Online (Sandbox Code Playgroud)

当我在没有取消引用的情况下运行它们时,除了排位赛之外,它们似乎相同吗?

`(+ 1 2 (+ 2 3)) ; => (clojure.core/+ 1 2 (clojure.core/+ 2 3))
'(+ 1 2 (+ 2 3)) ; => (+ 1 2 (+ 2 3))
Run Code Online (Sandbox Code Playgroud)

所以基本上我对'vs'感到困惑.我的理解是他们都引用了列表中的所有内容,这就是为什么我不确定为什么unquoting行为不同.基本上``的行为方式与我期望的'和'表现一样.

谢谢!

dan*_*lei 10

简短的回答是,不引用只能在反引号中起作用.在一个正常的引用表达式中,所有内容 - 包括~内部/后面的所有内容 - 只是按原样传递,而在反引号表达式中,内部/后面的所有内容都会~被评估(但其他所有内容都保持未评估状态).所以,不,不是反引号表达式中的所有内容都不会被评估 - 您可以~在其中使用它,将其用作一种模板,在其中"填充空白" ~.

编辑:引用(双关语)与您的问题相关的文档:

引用:

Quote (')
'form => (quote form)
Run Code Online (Sandbox Code Playgroud)

和(来自特殊表格部分):

(报价表)产生未评估的表格.

user=> '(a b c)
(a b c)
Run Code Online (Sandbox Code Playgroud)

注意,没有尝试调用函数a.返回值是3个符号的列表.

语法引用(也称为quasiquote,反引号):

对于列表/向量/集/映射,syntax-quote建立相应数据结构的模板.在模板中,非限定形式的行为就像递归语法引用一样,但是通过使用非引号或非引号拼接来限定表单,可以免除这种递归引用,在这种情况下,它们将被视为表达式并在模板中被替换为值或值序列.