В чем разница между 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.