Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a setfable nthcdr implementation exist?

I am using clisp and I wonder if there is any library with a setfable version of nthcdr that I can use.

like image 698
Paralife Avatar asked Dec 08 '10 13:12

Paralife


2 Answers

You can hack around it with:

(let ((lst (list 1 2 3 4))
      (n 2))
  (setf (cdr (nthcdr (1- n) lst)) '(5 6 7))
  l)
> (1 2 5 6 7)

Or define your own setf for it:

;; !!warning!!  only an example, lots of nasty edge cases
(defsetf nthcdr (n lst) (new-val) 
   `(setf (cdr (nthcdr (1- ,n) ,lst)) ,new-val))

I do not know why nthcdr does not have a setf defined. Even Alexandria seems to define setf for last, but not nthcdr.

PS. I would treat wanting to setf an nthcdr as a bad smell in your code.

like image 190
Beef Avatar answered Nov 07 '22 03:11

Beef


(defsetf my-nthcdr (n list) (store)
  (let ((tmp (gensym)))
    `(let ((,tmp (nthcdr (1- ,n) ,list)))
       (rplacd ,tmp ,store)
       (cdr ,tmp))))

Doesn't work when n is 0 though, you could make it work when LIST is a symbol, checking if N is zero either on macroexpansion time, but then it only works if N is a number, or including the check in the expanded code.

like image 1
drdo Avatar answered Nov 07 '22 04:11

drdo