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.
精彩评论