В чем разница между push и add-to-list?


28

Я обнаружил, что различные пакеты в их инструкциях по установке используют push или add-to-list (например, добавление каталога в путь загрузки), и мне было интересно, в чем разница и каков вариант использования для каждого из них.


1
Я изо всех сил пытался преобразовать код, использующий add-to-listв код, используя cl-pushnew, и я нашел это сообщение в блоге весьма поразительным: yoo2080.wordpress.com/2013/09/11/…
— dangom

Ответы:


22

То, что упоминает #zck, является одним отличием. Но если бы это было единственным отличием, тогда вы могли бы спросить об cl-pushnewи add-to-list.

Еще одно важное отличие: add-to-listэто функция, которая означает, что она оценивает все свои аргументы, в частности, первый. pushявляется макросом (как есть cl-pushnew) - он не оценивает свой второй аргумент; вместо этого это интерпретирует это как обобщенное место.

Например, если второй аргумент является символом, то он рассматривается как переменная, и значение первого аргумента ограничивается значением этого символа как переменная, и для переменной устанавливаются эти новые минусы.

Как add-to-listсказано в строке документа :

This is handy to add some elements to configuration variables,
but please do not abuse it in Elisp code, where you are usually
better off using `push' or `cl-pushnew'.

6
Также согласно add-to-list can't use lexical var ...; use push or cl-pushnew
— байтовому

(push (5 6) my-list)все равно выдает ошибку - 5это не функция. Чем это отличается от нашего add-to-listповедения?
— markasoftware

@markasoftware: что вы пытаетесь сделать? Если вы хотите сдвинуть список (5 6)на место (значение переменной), my-listто вам нужно создать список (5 6). Один из способов сделать это - использовать '(5 6); другой должен использовать (list 5 6). pushоценивает аргумент.
— Дрю

@ Теперь вы говорите, что он оценивает аргумент, но ваш ответ буквально гласит: «он не оценивает свой первый аргумент», что является источником моего замешательства.
— markasoftware

@markasoftware: извините; У меня была опечатка - я написал «первый аргумент», где я должен был написать «второй аргумент». Исправлено сейчас - спасибо. Второй аргумент push- это место, например, переменная. Первый аргумент вычисляется, ограничивается значением этой переменной, и для переменной устанавливаются эти новые минусы. add-to-listвычисляет свой первый аргумент для получения переменной, значение которой обновляется. pushне оценивает свой второй аргумент, который является переменной для обновления. Порядок arg обратный между двумя.
— Дрю

15

Из документации Emacs или C-h f push:

Макрос: push-имя списка элементов

Этот макрос создает новый список, автомобилем которого является элемент, а cdr которого является списком, указанным в listname, и сохраняет этот список в listname.

С той же страницы, или C-h f add-to-list:

Функция: элемент символа добавления в список и необязательное добавление сравнить-fn

Эта функция устанавливает символ переменной, помещая элемент в старое значение, если элемент еще не является членом этого значения.

Так что add-to-listтолько толкает, если элемент еще не там.


cl-pushnewведет себя как add-to-list.
— Сам Boosalis

15

Еще одно отличие:

pushдобавляет элемент в начало списка .

add-to-listпозволяет добавить элемент в начало или конец списка .

(setq testasdf nil)

(push 'a testasdf)

testasdf
(a)

(add-to-list 'testasdf 'b)

testasdf
(b a)

;; add element to the end
(add-to-list 'testasdf "hello" t)

testasdf
(b a "hello")
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.