В чем разница между списком и цитатой в Лиспе (Clojure, Emacs Lisp)?

Прочитав вводный материал по Lisp, я считаю, что следующие идентичны:

(list 1 2 3)

'(1 2 3)

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


person neo    schedule 09.10.2010    source источник
comment
Они похожи, на самом деле взгляните на мой вопрос здесь   -  person Lime    schedule 04.10.2015


Ответы (4)


Основное отличие состоит в том, что 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]
person Alex Taggart    schedule 09.10.2010
comment
этот ответ кажется нечестным, поскольку в нем не упоминается, что (list 1 2 '(+ 1 2)) по-прежнему является списком, но третий элемент не оценивается, но он не выражает разницу между '(1 2 (+ 1 2)) и (list '1 '2 '(+ 1 2)) - person Dmitry; 16.11.2016

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

(list 1 2 3) создаст новый список, не зависящий от всех остальных.

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

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

(list (+ 1 2) 3)     -->  (3 3)
(quote ((+ 1 2) 3))  -->  ((+ 1 2) 3)
person Trey Jackson    schedule 09.10.2010
comment
Мне понравилось, что вы указали разницу между их подписями, количеством аргументов. - person Daniel Dinnyes; 26.07.2012

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

Для списков:

'(1 2 3)

Выше приведен постоянный список, который будет создан читателем и оценен для себя, потому что он цитируется. Если он появляется в коде Lisp, компилятор каким-то образом встраивает эти данные в код 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)

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

person Rainer Joswig    schedule 09.10.2010

Их отношение может быть аналогично вызову функции с «именем функции» и funcall.

Когда вы не знаете, какую функцию вы получите во время выполнения, вы используете funcall.

Если вы не знаете, какой элемент вы можете получить во время выполнения, используйте list.


Для людей вроде меня, которые запутались из-за существования backquote и негласно считают это цитатой.

backquote не quote

Это макрос-читатель, который расширяется до quote, list или других:

(macroexpand ''(1 2));=> '(1 2)
(macroexpand '`(1 2));=> '(1 2)
(macroexpand '`(1 ,2));=> (list 1 2)
(macroexpand '`(1 ,@foo));=> (cons 1 foo)
(macroexpand '`(1 ,@foo 2));=> (cons 1 (append foo '(2)))
person nichijou    schedule 22.01.2021