help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Appending lists


From: Drew Adams
Subject: Re: Appending lists
Date: Thu, 17 Jun 2021 03:18:48 +0000

> >> What's a "deep copy"?
> >
> > It's a copy where every part of the object is separate, not
> > `eq' to the corresponding parts of the object that
> > you copied.
> >
> > For a cons, which is a tree, it would mean that neither car
> > nor cdr are shared between the original and the copy, and
> > that the same is true for any cars and cdrs that are,
> > themselves, conses.
> >
> > IOW, the tree is separate/independent from its copy.
> > When that's the case you can change any parts of either
> > without affecting the other.
> >
> > `C-h f copy-tree' describes the difference between what it
> > does (a deep copy) and what `copy-sequence' does (shallow
> > copy - doesn't copy cars.
> 
> deep copy = actual copy
> shallow copy = copy of references?

Did you read `C-h f copy-tree'?

No.  Everything involving list structure (conses)
uses references.

`copy-sequence' is a shallow copy - it copies only
the conses that make up the cdrs, so that you get
new conses for ONLY those - just the conses that
make up the _sequence_).

It copies only the flat, cdr list structure, not
any list structure in cars.  You get a new sequence,
but the sequence elements (the cars) share list
structure with the input sequence.

E.g., `copy-sequence' on the list `((1 2) 3 (4))'
gives you a new sequence (list) whose elements are
also `(1 2)', `3', and `(4)'.  The first and third
elements are not only `equal' to those of the input
sequence - they are `eq' to them.

`copy-tree' is a deep copy - it copies conses in
both cars and cdrs, so you get new list structure
(conses) everywhere.  There is NO cons in the
output that's `eq' to a cons in the input.

The result of `copy-tree' is a new `((1 2) 3 (4))'
list a new tree through and through.  Its first
element, `(1 2)' is not `eq' to the `(1 2)' of the
input list.  Same thing for its last element.

`copy-tree' results in a list that's `equal' to
the input list, but there is no cons in it that's
`eq' to a cons of the input.  `copy-sequence'
guarantees that conses in cars of the output
sequence ARE `eq' to those in the input.

(setq foo '((1 2) 3 (4)))

(setq sfoo (copy-sequence foo))

(eq foo sfoo)                 ; nil
(eq (car foo) (car sfoo))     ; t
(eq (caddr foo) (caddr sfoo)) ; t

(setq tfoo (copy-tree foo))

(eq foo tfoo)                 ; nil
(eq (car foo) (car tfoo))     ; nil
(eq (caddr foo) (caddr tfoo)) ; nil

`copy-tree' is more expensive.  `copy-sequence'
lets you continue to share sequence elements.

If two lists share any parts, then if you change
such a shared part in one it's changed also in
the other.  That's exactly the point of sharing.

It's also the "danger".  Don't share List
structure unless you intend to.  You may never
need to or want to.

You will need to be aware of list structure
and the possibility that it gets shared, when
playing with Lisp code that you didn't write,
at least.

And know about Lisp functions that can catch
you up on this kind of thing - functions called
"destructive" in the doc, i.e., functions that
can modify or share list structure.

____

[If you happen to know Fortran then think
COMMON blocks plus overlapping DIMENSION specs:
shared bits of overlapping memory, like Venn
diagrams.  Programs can act on different bits
in different ways.  Many large Fortran programs
were all about this sort of thing.  Likewise
some assembler programs.]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]