Clojure - 引用和语法引用的区别

17
(def x 1)
user=> '`~x
x
user=> `'~x
(quote 1)

有人可以解释一下评估是如何逐步进行的吗?


你的意思是等于 1 - Chiron
1个回答

17

单引号运算符返回您引用但未计算的表达式或符号。语法引用运算符返回您引用的表达式或符号(添加了名称空间),而不对其进行评估。语法取消引用运算符“撤销”语法引用运算符,但不是单引号。您可以嵌套语法引用和语法取消引用以执行奇怪而奇妙的技巧。我喜欢阅读的一个理解这些内容的类比是将语法引用和语法取消引用视为一架梯子的上下跑(可能的来源)。

在形式上`x中,x被语法引用,因此它不会被计算;相反,您会得到一个带名称空间的符号(例如user/x)。但在形式上`~x中,x再次被语法取消引用,因此它被计算:

user=> `~x
1

关于你的例子:

例子1

' 只是 (quote ...) 的简写。

因此 '`~x 变成了 (quote `~x)。这又变成了 (quote x)(记住 `~ 实际上并没有做什么),这就是为什么整个表达式求值为符号 x

例子2

`'~x 中,让我们先用 quote 替换 '`(quote ~x)。表达式被语法引用了,因此它不会被求值。

所以你可以把 表达式 (quote ~x) 视为“中间步骤”。但我们还没结束。在语法引用中的 x 是语法去引用的,就像我上面的例子一样。因此,即使这个表达式作为一个整体不会被求值,x 也将被求值,其值为 1。最终,得到的表达式为:(quote 1)

有关此主题的博客文章


2
@galdre所指的梯子隐喻来自于《精通Clojure宏》一书 https://pragprog.com/book/cjclojure/mastering-clojure-macros - Chiron
@Chiron 谢谢。我不记得在哪里遇到过了。 - galdre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接