views:

113

answers:

3

Hello. The title is self-explanatory. How can I build a new list X from another list Y (same structure), but the resulting list pointing somewhere else in memory area, practically, another object? I tried with make-list :initial-element Y or appending to an empty list, but I still get the same object. Thanks!

+2  A: 

You're probably wanting to use COPY-LIST.

Vatine
Yes, this is it. If I setf a place in the new list, the first one won't get changed. Thanks.
Sh1
In fact, the problem remains if I use a list-in-list. For instance, given a as '((1 2 3) (4 5 6)) and b as a copy of a, then setf (nth 0 (nth 0 b)) "4" will change both lists.
Sh1
Pay attention to the comment that's upvoted the most, and/or read the HyperSpec. COPY-LIST only copies a *list* - it creates fresh conses for the top-level and then just points to the old data (which, if the old data is a pointer, like another cons, will be shared between the two lists). COPY-TREE will recurse through your structure and create fresh conses at all levels, but other types of complex data structures may still be shared. To do this *completely* you have to write your own function, as there is no such thing as a generic copy function.
Xanthir
+11  A: 

Common Lisp

Use COPY-LIST to copy the first list level.

Use COPY-TREE to copy a tree of conses, a multi-level list will be copied on all levels.

Both COPY-TREE and COPY-LIST will only copy the conses and nothing else. The things in the list stay the same (meaning EQL, not EQ).

See the Common Lisp HyperSpec's The Conses Dictionary for these and related functions.

Rainer Joswig
A: 

My copy-list (using sbcl) worked.

REPL:

(defvar a '((1 2 3) (4 5 6)))

(defvar b (copy-tree a))

(setf (nth 0 (nth 0 b)) "4")

a

; ((1 2 3) (4 5 6)) is returned

b

;(("4" 2 3) (4 5 6)) is returned

Maybe if you gave us more source we could help.

Gutzofter