В Лиспе (Clojure, Emacs Lisp), в чем разница между списком и цитатой? - PullRequest
29 голосов
/ 09 октября 2010

Из прочтения вводного материала на Лиспе я теперь считаю следующее идентичным:

(list 1 2 3)

'(1 2 3)

Однако, судя по проблемам, с которыми я сталкиваюсь при использовании цитируемой формы в Clojure и Emacs Lisp, они не то же самое.Можете ли вы сказать мне, в чем разница?

Ответы [ 3 ]

35 голосов
/ 09 октября 2010

Основным отличием является то, что quote препятствует оценке элементов, тогда как list не делает:

user=> '(1 2 (+ 1 2))
(1 2 (+ 1 2))
user=> (list 1 2 (+ 1 2))
(1 2 3)

По этой причине (среди прочего) использование идиоматического замыкания заключается в использовании вектора, когдаописание буквальной коллекции:

user=> [1 2 (+ 1 2)]
[1 2 3]
9 голосов
/ 09 октября 2010

Списки цитирования (например, '(1 2 3)) должны обрабатываться осторожно (как правило, только для чтения).(см. SO ответы Когда использовать «цитата в Лиспе и Когда использовать» цитата в Лиспе ).

(list 1 2 3) будет «против» нового списка, независимо от всех других.

Вы можете увидеть пример ловушки использования списков в кавычках в руководстве для nconc.

И, как вы, вероятно, знаете, когда вы вызываете 'list - аргументы, очевидно, будут сравниваться с содержимым списка в кавычках.И 'quote принимает один аргумент против 'list с переменным числом аргументов.

(list (+ 1 2) 3)     -->  (3 3)
(quote ((+ 1 2) 3))  -->  ((+ 1 2) 3)
8 голосов
/ 09 октября 2010

В Common Lisp объекты в кавычках являются константными литеральными данными. Вы не должны изменять эти данные, так как последствия не определены. Возможные последствия: изменение общих данных, попытка изменить данные только для чтения, ошибка может сигнализировать, она может просто работать, ...

Для списков:

'(1 2 3)

Выше приведен постоянный список, который будет построен читателем и оценен сам по себе, поскольку он цитируется. Если он появляется в коде на Лиспе, компилятор каким-то образом вставит эти данные в код FASL.

(quote (1 2 3)) - это еще один способ написать это.

(list 1 2 3)

это вызов функции Common Lisp LIST с тремя аргументами 1, 2 и 3. При оценке результата получается новый новый список (1 2 3).

Аналогично:

'(1 . 2)   and  (cons 1 2)

'#(1 2 3)  and  (vector 1 2 3)

Один - это буквенные данные, а другой - вызов функции, которая создает такую ​​структуру данных.

...