I am using clisp and I wonder if there is any library with a setfable version of nthcdr that I can use.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
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.
回答2:
(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.