开发者

Quoting Confusion

Why does this series of clojure commands return false and not true? What is the difference between the result of statement 1 "C" and 2 "(quote 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

This question is somewhat similar to How does clojure's syntax-quote work?


In Clojure (and other Lisps) the ' is a shortcut for the form (quote ...). So when Clojure sees this:

('A 'B 'C)

which is "translated" by the reader into:

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

Each of those quote forms evaluates to a symbol, so (quote A) evaluates to the symbol named A. In Clojure, symbols are functions and can be applied, so ((quote A) (quote B) (quote C)) is actually a function call. From the docs:

"Symbols, just like Keywords, implement IFn for invoke() of one argument (a map) with an optional second argument (a default value). For example ('mysym my-hash-map :none) means the same as (get my-hash-map 'mysym :none)."

So what happens is that C is the default value and that's why it's returned.

Meanwhile, this

'('A 'B 'C)

is translated by the reader into

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

Which is actually a list of three elements, each of which is a list of two elements, the symbol quote and another symbol (in this case A, B, C).

So, (last '('A 'B 'C)) is actually (quote C). That's the difference between those two results, C is the symbol with the name C while (quote C) is a list of two elements.

You can confirm this:

user=> (class ('A 'B 'C))
clojure.lang.Symbol
user=> (class (last '('A 'B 'C)))
clojure.lang.PersistentList
user=> 

Hope that's clear!


('x 'y) is very unusual, for just this reason. Usually you want '(x y), which is a list of the literal symbols x and y. If you quote TWICE with '('x 'y), you get a list with (quote x) instead: the literal symbol quote, followed by the literal symbol x.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜