Jaka jest różnica między wypychaniem a dodawaniem do listy?

28

Przekonałem się, że różne pakiety w instrukcjach instalacji używają push lub add-to-list (na przykład dodając katalog do ścieżki ładowania) i zastanawiałem się, jaka jest różnica i jaki byłby przypadek użycia każdego z nich.

złodziej
źródło
1
Próbowałem przekonwertować kod za pomocą add-to-listna kod za pomocą cl-pushnewi uważam, że ten post na blogu jest dość pouczający: yoo2080.wordpress.com/2013/09/11/…
dangom,

Odpowiedzi:

22

To, o czym wspomina #zck, to jedna różnica. Ale gdyby to była jedyna różnica, możesz zapytać o cl-pushnewi add-to-list.

Kolejna ważna różnica: add-to-listjest funkcją, która oznacza, że ​​ocenia wszystkie argumenty, w szczególności pierwszy. pushjest makrem (jak jest cl-pushnew) - nie ocenia drugiego argumentu; zamiast tego interpretuje to jako uogólnione miejsce.

Na przykład, jeśli drugi argument jest symbolem, wówczas jest on traktowany jako zmienna, a wartość pierwszego argumentu jest traktowana jako wartość tego symbolu jako zmienna, a zmienna jest ustawiana na te nowe minusy.

Jak add-to-listmówi ciąg dokumentów :

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'.
Drew
źródło
6
Również według bajtowego kompilatora:add-to-list can't use lexical var ...; use push or cl-pushnew
Malabarba
(push (5 6) my-list)wciąż daje mi błąd - 5nie jest funkcją. Czym różni się to od add-to-listzachowania?
markasoftware
@markasoftware: Co próbujesz zrobić? Jeśli chcesz przesunąć listę (5 6)na miejsce (wartość zmiennej) my-list, musisz utworzyć listę (5 6). Jednym ze sposobów na to jest użycie '(5 6); innym jest użycie (list 5 6). pushocenia argument.
Drew
@Drew, mówisz teraz, że ocenia argument, ale twoja odpowiedź dosłownie brzmi „nie ocenia pierwszego argumentu”, co jest źródłem mojego zamieszania.
markasoftware
@markasoftware: Przepraszam; Miałem literówkę - napisałem „pierwszy argument”, w którym powinienem napisać „drugi argument”. Poprawione teraz - dzięki. Drugim argumentem pushjest miejsce, takie jak zmienna. Pierwszy argument jest obliczany, przetwarzany na wartość tej zmiennej, a zmienna jest ustawiana na te nowe minusy. add-to-listocenia swój pierwszy argument, aby wygenerować zmienną, której wartość jest aktualizowana. pushnie ocenia drugiego argumentu, który jest zmienną do aktualizacji. Kolejność arg jest odwrócona między nimi.
Drew
15

Z dokumentacji Emacsa lub C-h f push:

Makro: nazwa listy elementów push

To makro tworzy nową listę, której samochód jest elementem, a której cdr jest listą określoną przez listname, i zapisuje tę listę w liście name.

Z tej samej strony lub C-h f add-to-list:

Funkcja: element symbolu dodaj do listy i opcjonalnie dodaj porównaj fn

Ta funkcja ustawia symbol zmiennej poprzez przypisanie elementu do starej wartości, jeśli element nie jest już członkiem tej wartości.

add-to-listPcha więc tylko wtedy, gdy elementu już nie ma.

zck
źródło
cl-pushnewzachowuje się jak add-to-list.
sam boosalis
15

Kolejna różnica:

pushdodaje element na początku listy .

add-to-listpozwala dodać element na początku lub na końcu listy .

(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")
cofnie się
źródło