Par exemple, disons que j'ai une liste de chaînes L
, peut-être à partir d'un &rest
argument. Que puis-je faire pour L
que cela ait le même effet que le suivant?
(concat (first L) (second L) ... (last L))
(Je sais que mapconcat
cela fonctionnerait ici pour cet exemple, mais je cherche un processus général.)
Ce que vous vouliez faire ressemble à un pliage ou à un dépliage d'une séquence d'objets du même type. Il est tentant de l'utiliser
apply
à cette fin, car dans de nombreux cas, cela fonctionnera en effet. Mais ce n'est pas exactement le bon outil pour cela, et voici pourquoi:apply
est un mécanisme de méta-programmation, non seulement cela, il est aussi trop général pour la tâche car il peut gérer des séquences d'objets de différents types, n'appelant pas nécessairement des fonctions de deux arguments. Par conséquent, vous obtiendrez parfois un comportement incorrect, par exemple:Mais intuitivement, vous vous attendriez à une incompatibilité de type ici.
Il n'y a aucun moyen de s'assurer
apply
qu'il sera en mesure de traiter autant d'arguments que vous pouvez lui donner, c'est généralement une limite imposée par l'implémentation du langage.La fonction appelée par
apply
pourra obtenir une référence de la liste des arguments qui lui est passée de cette manière. Cela n'est pas non plus évident et peut conduire à des erreurs plus tard:Si la liste d'arguments est copiée, vous payez le prix de consommer plus de mémoire que nécessaire, mais si elle n'est pas copiée (passée telle quelle), vous risquez de gâcher la liste, si la fonction appelée la modifie.
Donc, la meilleure façon de le faire est d'utiliser
cl-reduce
. L'avantage est qu'il a été spécialement conçu pour effectuer ce type de tâches.la source