On 2018-10-13 12:29 am, Aaron Hill wrote:
According to the docs [1], assoc-set! (and family) may modify the
original alist.  So whether a copy is made or not depends on an
implementation detail.  Near as I can tell, the original alist is
modified in-place when the key is found within.  But when the key is
new, the result of using acons to append the new key/value to the head
of the list results in a copy being returned.

[1]:
https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Adding-or-Setting-Alist-Entries.html#Adding-or-Setting-Alist-Entries

Nope, I'm wrong about copying. acons (and therefore assoc-set!) does not copy (shallow or deep). Consider the following:

guile> (define a '((one . 1) (two . 2)))
guile> (define b (assoc-set! a 'three 3))
guile> a
((one . 1) (two . 2))
guile> b
((three . 3) (one . 1) (two . 2))
guile> (define c (assoc-set! a 'three 3))
guile> c
((three . 3) (one . 1) (two . 2))
guile> (eq? b c)
#f
guile> (equal? b c)
#t
guile> (eq? a (cdr b))
#t
guile> (eq? (cdr b) (cdr c))
#t
guile> (set! a (assoc-set! a 'two 2.2))
guile> a
((one . 1) (two . 2.2))
guile> b
((three . 3) (one . 1) (two . 2.2))
guile> c
((three . 3) (one . 1) (two . 2.2))

While "b" and "c" are unique as far as the initial node in their respective lists (because acons returns a new list), they share the remainder with the same nodes within the original list. So, modification to the list that "a" references will propagate to "b" and "c".

Upon reflection, this all makes sense. So, one should probably be explicit about copying and use list-copy (shallow) or copy-tree (deep), as needed.

-- Aaron Hill

_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to