Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I copy a list and not share structure?

Tags:

common-lisp

Wow, I'm totally not understanding this bit!

I have a list, L1. I want to make a copy, L2 such that, when I modify L2, L1 remains unchanged. I'd-a thought that's what copy-seq was for, but it's not behaving as expected.

(defun tcopy ()
  (let ((seq1 nil)
        (seq2 nil))
    (setf seq1 (list (list 11 22) (list 33 44 55)))
    (setf seq2 (copy-seq seq1))        
    (format t "before -- s1: ~a s2: ~a~%" seq1 seq2)
    (setf (nth 1 (nth 1 seq2)) 99)
    (format t "after --  s1: ~a s2: ~a~%" seq1 seq2)))

And the output:

? (tcopy)
before -- s1: ((11 22) (33 44 55)) s2: ((11 22) (33 44 55))
after --  s1: ((11 22) (33 99 55)) s2: ((11 22) (33 99 55)) ; Undesired: s1 is modified
NIL
? 

I also tried the following:

;(setf seq2 (copy-seq seq1))
(setf seq2 (reduce #'cons seg1 :from-end t :initial-value nil))

It gives the same results. Lisp-n00b, here; what am I missing?!

Thanks!

like image 633
Olie Avatar asked Dec 21 '22 01:12

Olie


1 Answers

COPY-SEQ only copies the top-level sequence. Not any subsequences. (COPY-LIST behaves the same way.)

COPY-TREE copies a tree of cons cells. Thus it will also copy lists of lists of lists ...

like image 139
Rainer Joswig Avatar answered Jun 01 '23 11:06

Rainer Joswig