Reputation: 25
In lisp, I have the following example code:
(setf list1 '("a" "b" "c" ))
(setf list2 '())
(setf list2 list1)
(setf (nth 2 list1) "d")
(princ list1)
(princ list2)
I want the result to be:
(a b d)(a b c)
but it instead reassigns the nth element of both 'list1' AND 'list2', resulting in:
(a b d)(a b d)
I'm assuming it's because I set list2 equal to list1 earlier in the code, but usually when you set variables equal to one another, they don't change like that. What's going on here?
Upvotes: 0
Views: 61
Reputation: 1069
When you assign lists in lisp, no copying happens. The third line from your question:
(setf list2 list1)
does not copy the list, but rather sets list2 to also refer to the same cons cell as list1. If you want a fresh list, instead use copy-list:
(setf list2 (copy-list list1))
Which will set list2 to be a shallow copy of list1; that is to say that all the CARs of the CONS cells in list1 and list2 will be the same.
Upvotes: 3
Reputation: 25
In case no one is able to help me, I came up with a solution to override the issue, although it's not very elegant:
(setq list1 '("a" "b" "c"))
(setq list2 '())
(setq i 0)
(loop
(setf list2 (append list2'(0)))
(setf (nth i list2)(nth i list1))
(setq i (+ i 1))
(when (= i (list-length list1)) (return)))
(setf (nth 2 list1) "d")
(princ list1)
(princ list2)
Still very curious why (setf (nth N L) T)
resets the nth element of all lists whose values have been equated using set
.
Upvotes: 0