J'utilise clisp et je me demande s'il y a une bibliothèque avec une version setfable de nthcdr que je peux utiliser.Est-ce qu'une implémentation setfable nthcdr existe?
7
A
Répondre
5
Vous pouvez pirater autour avec:
(let ((lst (list 1 2 3 4))
(n 2))
(setf (cdr (nthcdr (1- n) lst)) '(5 6 7))
l)
> (1 2 5 6 7)
Ou définir votre propre setf pour elle:
;; !!warning!! only an example, lots of nasty edge cases
(defsetf nthcdr (n lst) (new-val)
`(setf (cdr (nthcdr (1- ,n) ,lst)) ,new-val))
Je ne sais pas pourquoi nthcdr n'a pas setf défini. Même Alexandria semble définir setf pour la fin, mais pas nthcdr.
PS. Je traiterais voulant mettre un nthcdr comme une mauvaise odeur dans votre code.
1
(defsetf my-nthcdr (n list) (store)
(let ((tmp (gensym)))
`(let ((,tmp (nthcdr (1- ,n) ,list)))
(rplacd ,tmp ,store)
(cdr ,tmp))))
ne fonctionne pas lorsque n est 0 cependant, vous pouvez le faire fonctionner lorsque la liste est un symbole, vérifier si N est égal à zéro, soit à l'heure de macroexpansion, mais il ne fonctionne que si N est un nombre, ou y compris la vérification dans le code développé.
Pourquoi est-ce une mauvaise odeur? Surtout quand vous laissez entendre qu'il n'y a aucune raison de ne pas avoir défini un setfable nthcdr. – Paralife
La raison pour laquelle je le veux est que je veux injecter chaque nœud d'un sexp avec un élément id et en même temps stocker chaque nœud dans une table de hachage tout en traversant l'arbre sexp. Donc, si la décoration ne se passe pas sur place, les valeurs de la table de hachage ne verront pas les sous-noeuds décorés – Paralife
Notez qu'en général, dans Common Lisp, ce qui se passe lorsque vous modifiez des données littérales n'est pas défini. –