¿Cuál es la diferencia entre push y add-to-list?

28

Descubrí que los diferentes paquetes en sus instrucciones de instalación usan push o add-to-list (por ejemplo, agregar un directorio a load-path) y me preguntaba cuál es la diferencia y cuál sería el caso de uso para cada uno.

ladrón de las sombras
fuente
1
Estaba luchando para convertir el código usando add-to-lista código usando cl-pushnew, y encontré que esta publicación del blog es bastante esclarecedora: yoo2080.wordpress.com/2013/09/11/…
dangom

Respuestas:

22

Lo que #zck menciona es una diferencia. Pero si esa fuera la única diferencia, entonces podría preguntar sobre cl-pushnewy add-to-list.

Otra diferencia importante: add-to-listes una función, lo que significa que evalúa todos sus argumentos, en particular, el primero. pushes una macro (como está cl-pushnew): no evalúa su segundo argumento; en cambio, lo interpreta como un lugar generalizado.

Por ejemplo, si el segundo argumento es un símbolo, entonces se considera como una variable, y el valor del primer argumento se incluye en el valor de ese símbolo como una variable, y la variable se establece en esa nueva desventaja.

A medida que la cadena de documentación de add-to-listdice:

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'.
Dibujó
fuente
66
También según el compilador de bytes:add-to-list can't use lexical var ...; use push or cl-pushnew
Malabarba
(push (5 6) my-list)Todavía me da un error, 5no es una función. ¿Cómo es esto diferente al add-to-listcomportamiento de?
markasoftware
@markasoftware: ¿Qué intentas hacer? Si desea llevar la lista (5 6)al lugar (valor de la variable) my-list, debe crear la lista (5 6). Una forma de hacerlo es usar '(5 6); otro es para usar (list 5 6). pushevalúa el argumento.
Dibujó
@Drew, dices ahora que evalúa el argumento, pero tu respuesta literalmente dice "no evalúa su primer argumento", que es la fuente de mi confusión.
markasoftware
@markasoftware: lo siento; Tuve un error tipográfico: escribí "primer argumento" donde debería haber escrito "segundo argumento". Corregido ahora, gracias. El segundo argumento pushes un lugar, como una variable. Se evalúa el primer argumento, consed en el valor de esa variable, y la variable se establece en esos nuevos inconvenientes. add-to-listevalúa su primer argumento para producir la variable cuyo valor se actualiza. pushno evalúa su segundo argumento, que es la variable a actualizar. El orden arg se invierte entre los dos.
Dibujó
15

De la documentación de Emacs , o C-h f push:

Macro: elemento de lista nombre de inserción

Esta macro crea una nueva lista cuyo auto es elemento y cuyo cdr es la lista especificada por listname, y guarda esa lista en listname.

Desde la misma página, o C-h f add-to-list:

Función: elemento de símbolo de agregar a la lista y opcional agregar compare-fn

Esta función establece el símbolo de la variable al convertir el elemento en el valor anterior, si el elemento aún no es miembro de ese valor.

Entonces add-to-listsolo empuja si el elemento ya no está allí.

zck
fuente
cl-pushnewse comporta como add-to-list.
Sam Boosalis
15

Otra diferencia:

pushagrega elemento al comienzo de la lista .

add-to-listle permite agregar elementos al principio o al final de la lista .

(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")
undostres
fuente