Clojure -引用混淆



抱歉,标题太模糊了:)

我不熟悉宏,很难理解这两个语句之间的区别:

`(+ 1 2 ~(+ 2 3)) ; => (clojure.core/+ 1 2 5)
'(+ 1 2 ~(+ 2 3)) ; => (+ 1 2 (clojure.core/unquote (+ 2 3)))

当我在不加反引号的情况下运行它们时,它们看起来完全相同,而不是限定符?

`(+ 1 2 (+ 2 3)) ; => (clojure.core/+ 1 2 (clojure.core/+ 2 3))
'(+ 1 2 (+ 2 3)) ; => (+ 1 2 (+ 2 3))

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

谢谢!

简短的回答是,取消引号只在反引号中起作用。在一个正常的引号表达式中,所有的东西——包括~和里面/后面的所有东西——都是按原样传递的,而在一个反引号表达式中,~里面/后面的所有东西都是求值的(但其他所有东西都保持不求值)。所以,不,不是反引号表达式中的所有内容都保持未求值-您可以在其中使用~,将其用作一种模板,在那里您用~"填充空白"。

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

:

Quote (')
'form => (quote form)

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

(引用形式)产生未求值的形式。

user=> '(a b c)
(a b c)

注意,这里没有尝试调用函数a。返回值是一个包含3个符号的列表。

引号语法(也称为准引号、反引号):

对于Lists/Vectors/Sets/Maps, syntax-quote建立一个模板相应的数据结构。在模板内,不合格表单的行为就像是递归地加了语法引号,但表单可以这样做通过使用unquote来限定它们,从而免除这种递归引用或取消引号拼接,在这种情况下,它们将被视为表达式并在模板中被它们的值或值序列替换,分别。

尝试对前两个表达式的结果运行eval。第一个带有',"展开"为(+ 1 2 3),其计算结果为6。第二个,带',"展开"为(+ 1 2 (unquote (+ 1 2))),并且unquote在该上下文中无效,因为您不再在引号内!所以这完全不能求值。

基本上'和'有两个区别:

  • 的命名空间限定所有
  • '允许取消引用

最新更新