This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

How to modify elements of a list

2 posts · 745 views

Hi all, I'm approching Common Lisp but I'm having problems with functions that manipulate lists.
In my program I have something like this:

(defun ac(var val domain)
(let*
(
(x nil)
(dom nil)
)
(setq dom (copy-list domain))

(dolist (x dom)
(if(equal (third x) var)
(progn
(setf (first x) val)
(setf (second x) val)
(return)
)
)
) ; end of dolist

(println dom)
(println domain)
...
...

Println is a function of mine wich displays elements of a list.
The problem is that "dom" and "domain" contain the same elements when I print them, while I want "domain" to store the initial elements.
How can I do that?
Thanks

Re: How to modify elements of a list

First, use code markers to post source code, this makes it more readable and maintains formatting. Also, there are certain conventions when writing lisp, most importantly not to leave parentheses on their own lines. Since Lisp is supposed to be read by humans by indentation, it increases readability by decreasing vertical distances. Your code reformatted:
(defun ac (var val domain)
  (let* ((x nil)
         (dom nil))
    (setq dom (copy-list domain))
    (dolist (x dom)
      (if (equal (third x) var)
          (progn
            (setf (first x) val)
            (setf (second x) val)
            (return))))
    (println dom)
    (println domain)))
Your problem is that COPY-LIST copies the list, without touching the contents. If you want to copy all conses in a nested list, which forms a tree, you can use COPY-TREE.

Note that Common Lisp doesn't have lists as such. There are only cons cells, which are essentially binary tree nodes, and lists are implemented fully imbalanced trees. In general it is best not to mutate those lists, since their behaviour is somewhat unintuitive, if you don't fully understand the cons cell implementation.