':a
является сокращением для (quote :a)
.
(eval '(quote form))
возвращает form
по определению. То есть, если функция Clojure eval
получает в качестве аргумента структуру списка, первым элементом которой является символ quote
, она возвращает второй элемент указанной структуры списка, не преобразовывая его каким-либо образом (таким образом, говорят, что цитируемая форма не оценивается). Другими словами, поведение eval
отправляется, когда его аргумент является структурой списка в форме (quote foo)
и возвращает foo
без изменений, независимо от того, что это .
Когда вы записываете в вашей программе литерал :a
, он получает , считываемое как ключевое слово :a
; то есть конкретный фрагмент текста :a
преобразуется в структуру данных в памяти, которая называется ключевым словом :a
(Lisp, будучи гомоиконичным, означает, что иногда трудно различить текстовое представление данных Lisp и сами данные, даже если это будет полезно для пояснительных целей ...).
Структура данных в памяти, соответствующая литералу :a
, является объектом Java, который предоставляет ряд методов и т. Д. И который имеет интересное свойство, что функция eval
, когда она получает этот объект данных в качестве аргумента возвращает его без изменений. Другими словами, ключевое слово «оценка для себя», о котором вы спрашиваете, - это просто поведение, которое eval
отправляет при передаче ключевого слова в качестве аргумента .
Таким образом, когда eval
видит ':a
, он обрабатывает его как форму в кавычках и возвращает вторую ее часть, которая оказывается :a
. Когда, с другой стороны, eval
видит :a
, он обрабатывает его как ключевое слово и возвращает его без изменений. Возвращаемое значение одинаково в обоих случаях (это просто ключевое слово :a
); процесс оценки немного отличается.
Семантика Clojure - на самом деле семантика Lisp для любого диалекта Lisp - определяется в терминах значений, возвращаемых функцией, и побочных эффектов, вызванных функцией eval
, когда она получает различные структуры данных Lisp в качестве аргументов , Таким образом, вышеприведенное объясняет, что на самом деле должно происходить, когда вы записываете ':a
или :a
в своей программе (такой код, как (println :a)
, может быть скомпилирован в эффективный байт-код, который, конечно, фактически не кодирует функцию eval
; но семантика всегда сохраняется, так что она все еще действует , как если бы eval
получала структуру списка, содержащую символ println
и ключевое слово :a
).
Ключевая идея здесь заключается в том, что независимо от того, является ли оцениваемая форма ':a
или :a
, структура данных ключевого слова создается во время чтения; затем, когда одна из этих форм оценивается, эта структура данных возвращается без изменений - хотя по разным причинам.