[Top][All Lists]

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

append! on a deep-cloned list slot

From: Brandon Invergo
Subject: append! on a deep-cloned list slot
Date: Mon, 29 Apr 2019 09:44:09 +0100
User-agent: mu4e 1.2.0; emacs 26.2


I don't understand the following behavior:

scheme@(guile-user)> (use-modules (oop goops))
scheme@(guile-user)> (define-class <xyzzy> () (gob #:accessor gob 
#:init-keyword #:gob))
scheme@(guile-user)> (define a (make <xyzzy> #:gob '(foo)))
scheme@(guile-user)> (define b (deep-clone a))
scheme@(guile-user)> (append! (gob b) '(bar))
$1 = (foo bar)
scheme@(guile-user)> (gob a)
$2 = (foo bar)

Why does append! also modify the list in object a?  I was under the
impression that deep-clone allocates new memory for all slots in b.

And if append! clobbers the source memory, why does using set! on the
accessor work without overwriting the source memory?

scheme@(guile-user)> (define a (make <xyzzy> #:gob '(foo)))
scheme@(guile-user)> (define b (deep-clone a))
scheme@(guile-user)> (set! (gob b) (append (gob b) '(bar)))
$3 = (foo bar)
scheme@(guile-user)> (gob a)
$4 = (foo)

I guess in this latter case, the call to append definitely allocates new
memory for the list and sets the slot to point to the new memory.  Isn't
that what was supposed to happen with the deep-clone, too?  Or is
deep-clone just cloning the pointer to the original list's memory
without allocating new memory and copying the data to it?

The manual says "‘append’ doesn’t modify the given lists, but the return
may share structure with the final OBJ."  That implies to me that the
second method is still unsafe: if I'm actually appending a list stored
in some variable that I might be referencing later, modifying (gob b)
might end up changing the list bound to that variable.

So, what's the best way to do this?  Skip the deep-clone, make a new
instance of the object from scratch (obviously, the real world example I
have in mind is slightly more complicated than the case above), and use



reply via email to

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