Quelle est la différence entre push et add-to-list?

28

J'ai trouvé que différents packages dans leurs instructions d'installation utilisent soit push, soit add-to-list (par exemple en ajoutant un répertoire à load-path) et je me demandais quelle était la différence et quel serait le cas d'utilisation de chacun.

shadowthief
la source
1
J'avais du mal à convertir le code à l'aide add-to-listde code à l'aide cl-pushnew, et j'ai trouvé cet article de blog assez instructif: yoo2080.wordpress.com/2013/09/11/…
dangom

Réponses:

22

Ce que #zck mentionne est une différence. Mais si c'était la seule différence, vous pourriez poser des questions sur cl-pushnewet add-to-list.

Une autre différence importante: add-to-listest une fonction, ce qui signifie qu'elle évalue tous ses arguments, en particulier le premier. pushest une macro (telle cl-pushnewquelle) - elle n'évalue pas son deuxième argument; au lieu de cela, il l'interprète comme un lieu généralisé.

Par exemple, si le deuxième argument est un symbole, il est considéré comme une variable, et la valeur du premier argument est consignée sur la valeur de ce symbole en tant que variable, et la variable est définie sur ce nouveau contre.

Comme le dit la chaîne de doc de 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'.
A dessiné
la source
6
Toujours selon le compilateur d'octets:add-to-list can't use lexical var ...; use push or cl-pushnew
Malabarba
(push (5 6) my-list)me donne toujours une erreur - 5n'est pas une fonction. En quoi est-ce différent add-to-listdu comportement de?
markasoftware
@markasoftware: qu'essayez-vous de faire? Si vous souhaitez pousser la liste (5 6)à l'endroit (valeur de la variable), my-listvous devez créer la liste (5 6). Une façon de le faire est d'utiliser '(5 6); une autre est d'utiliser (list 5 6). pushévalue l'argument.
Drew
@Drew vous dites maintenant qu'il évalue l'argument, mais votre réponse dit littéralement "qu'il n'évalue pas son premier argument", ce qui est la source de ma confusion.
markasoftware
@markasoftware: je suis désolé; J'ai eu une faute de frappe - j'ai écrit "premier argument" où j'aurais dû écrire "deuxième argument". Corrigé maintenant - merci. Le deuxième argument de pushest un endroit, comme une variable. Le premier argument est évalué, pris en compte sur la valeur de cette variable, et la variable est définie sur ce nouveau contre. add-to-listévalue son premier argument pour produire la variable dont la valeur est mise à jour. pushn'évalue pas son deuxième argument, qui est la variable à mettre à jour. L'ordre d'argument est inversé entre les deux.
Drew
15

De la documentation Emacs , ou C-h f push:

Macro: push nom de la liste des éléments

Cette macro crée une nouvelle liste dont la voiture est élément et dont cdr est la liste spécifiée par listname et enregistre cette liste dans listname.

De la même page, ou C-h f add-to-list:

Fonction: élément de symbole d'ajout à la liste et ajout facultatif de comparaison-fn

Cette fonction définit le symbole de variable en mettant l'élément sur l'ancienne valeur, si l'élément n'est pas déjà membre de cette valeur.

Donc, add-to-listne pousse que si l'élément n'est pas déjà là.

zck
la source
cl-pushnewse comporte comme add-to-list.
sam boosalis
15

Une autre différence:

pushajoute un élément au début de la liste .

add-to-listvous permet d'ajouter un élément au début ou à la fin de la liste .

(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
la source