Search code examples
for-looplispcommon-lispelisp

cl-loop destructively modify cons cell


I want to update the contents of a cons cell in a cl-loop construct. For example, say I have the following

(setq lst '(("a" . "b") ("c" . "d")))
(cl-loop for (k . v) in lst
   when (string= k "b")
   do (setq v "f") ; how to destructively change this?
   and return t)

I was thinking I would need to use a setcdr, but figured that would require using the loop without destructuring. I doubt it is possible with the way I have it now without getting a pointer to that object, but I'm not sure.


Solution

  • You can have multiple for-clauses in a loop:

    (let ((alist (copy-tree '(("a" . "b") ("b" . "c") ("c" . "d") ("b" . "e")))))
      (cl-loop for cell in alist
               for (k . v) = cell
               when (string= k "b")
               do (setcdr cell "f")
               and return t)
      alist)
    ;=> (("a" . "b") ("b" . "f") ("c" . "d") ("b" . "e"))