В Clojure (и других Лиспах) '
является ярлыком для формы (quote ...)
. Итак, когда Clojure видит это:
('A 'B 'C)
который «переводится» читателем на:
((quote A) (quote B) (quote C))
Каждая из этих форм кавычек оценивается как символ, поэтому (quote A)
оценивается как символ с именем A. В Clojure символы являются функциями и могут применяться, поэтому ((quote A) (quote B) (quote C))
на самом деле является вызовом функции. Из документов:
"Символы, подобно ключевым словам, реализуют IFn для invoke () одного аргумента (карты) с необязательным вторым аргументом (значением по умолчанию). Например ('mysym my-hash-map: none) означает то же самое as (получить my-hash-map 'mysym: none). "
Так что получается, что C
является значением по умолчанию, и поэтому оно возвращается.
Между тем, это
'('A 'B 'C)
переводится читателем на
(quote ((quote A) (quote B) (quote C)))
На самом деле это список из трех элементов, каждый из которых представляет собой список из двух элементов: символа quote
и другого символа (в данном случае A
, B
, C
).
Итак, (last '('A 'B 'C))
на самом деле (quote C)
. В этом разница между этими двумя результатами: C
- это символ с именем C, а (quote C)
- список из двух элементов.
Вы можете подтвердить это:
user=> (class ('A 'B 'C))
clojure.lang.Symbol
user=> (class (last '('A 'B 'C)))
clojure.lang.PersistentList
user=>
Надеюсь, это понятно!