引用混乱

时间:2011-03-20 17:47:42

标签: clojure

为什么这一系列的clojure命令会返回false而不是true?声明1“C”和2“(引用C)”的结果有什么区别?

; SLIME 2009-03-04
user> ('A 'B 'C)
C
user> (last '('A 'B 'C))
(quote C)
user> (= ('A 'B 'C) (last '('A 'B 'C)))
false

这个问题与How does clojure's syntax-quote work?

有些相似

2 个答案:

答案 0 :(得分:7)

在Clojure(和其他Lisps)中,'(quote ...)形式的快捷方式。所以当Clojure看到这个时:

('A 'B 'C)

由读者“翻译”成:

((quote A) (quote B) (quote C))

这些引用形式中的每一个都评估为符号,因此(quote A)计算为名为A的符号。在Clojure中,符号是函数并且可以应用,因此((quote A) (quote B) (quote C))实际上是函数调用。来自文档:

“符号,就像关键字一样,为一个参数(一个映射)的invoke()实现IFn,带有可选的第二个参数(默认值)。例如('mysym my-hash-map:none)表示相同as(get my-hash-map'mysym:none)。“

所以会发生C是默认值,这就是它返回的原因。

同时,这个

'('A 'B 'C)

由读者翻译成

(quote ((quote A) (quote B) (quote C)))

实际上是三个元素的列表,每个元素都是两个元素的列表,符号quote和另一个符号(在本例中为AB,{{ 1}})。

因此,C实际上是(last '('A 'B 'C))。这是两个结果之间的差异,(quote C)是名称为C的符号,而C是两个元素的列表。

您可以确认:

(quote C)

希望这很清楚!

答案 1 :(得分:1)

出于这个原因,

('x'y)是非常不寻常的。通常你想要'(x y),这是文字符号x和y的列表。如果您使用'('x'y)引用TWICE,则会得到一个带(引用x)的列表:文字符号引号,后跟文字符号x。