В Lisp (Clojure, Emacs Lisp), в чем разница между списком и цитатой?
Из чтения вводного материала по Lisp, я теперь считаю, что следующее: 1/
(list 1 2 3)
'(1 2 3)
Однако, судя по проблемам, с которыми я сталкиваюсь при использовании цитируемой формы как в Clojure, так и в Emacs Lisp, они не совпадают. Можете ли вы сказать мне, в чем разница?
Ответы
Ответ 1
Основное отличие состоит в том, что quote
предотвращает оценку элементов, тогда как list
не:
user=> '(1 2 (+ 1 2))
(1 2 (+ 1 2))
user=> (list 1 2 (+ 1 2))
(1 2 3)
По этой причине (среди прочих), идиоматический clojure использует вектор при описании литерала:
user=> [1 2 (+ 1 2)]
[1 2 3]
Ответ 2
Котируемые списки (например, '(1 2 3)
) следует тщательно обрабатывать (как правило, только для чтения). (см. ответы SO Когда использовать 'quote в Lisp и Когда использовать' quote в Lisp).
(list 1 2 3)
будет "засовывать" новый список, независимо от всех остальных.
Вы можете увидеть пример ложного использования цитируемых списков в manual для nconc
.
И, как вы, вероятно, знаете, когда вы вызываете 'list
- аргументы, очевидно, будут вычисляться в сравнении с содержимым цитируемого списка. И 'quote
принимает один аргумент, вместо 'list
переменное число аргументов.
(list (+ 1 2) 3) --> (3 3)
(quote ((+ 1 2) 3)) --> ((+ 1 2) 3)
Ответ 3
В Common Lisp цитируемые объекты являются постоянными литералами. Вы не должны изменять эти данные, так как последствия undefined. Возможные последствия: изменение общих данных, попытка изменить данные только для чтения, может быть сообщена ошибка, она может просто работать,...
Для списков:
'(1 2 3)
Выше - это список констант, который будет построен читателем и оценен сам по себе, поскольку он цитируется. Если он появляется в коде Lisp, компилятор каким-то образом вставляет эти данные в код FASL.
(quote (1 2 3))
- это еще один способ его записи.
(list 1 2 3)
это вызов функции Common Lisp LIST
с тремя аргументами 1
, 2
и 3
. При оценке результат представляет собой новый новый список (1 2 3)
.
Similar:
'(1 . 2) and (cons 1 2)
'#(1 2 3) and (vector 1 2 3)
Один - это буквальные данные, а другой - вызов функции, который создает такую структуру данных.