I am little bit confused by the result of this example:
(define mk-q
(lambda ()
(let ([l '(x)])
(cons l l))))
(define q (mk-q))
q
=> ((x) x)
(set-car! (cdr q) 'y)
=> ((y) y)
I am wondering why both x
atoms have been replaced by set-car!
procedure (my first guess for what the result would be was ((x) y)
)?
For example:
(define mk-q2
(lambda ()
(let ([l '(x)])
(cons l (cons l l)))))
(define q2 (mk-q2))
(set-car! (cdr q2) 'y)
=> ((x) y x) which fits my understanding of set-car!
Why are both x
s in the first example replaced?
In the first example, you have something equivalent to this:
(define cell (cons 'x null))
(define q (cons cell cell))
As you can see, there's only one cons
cell with x
at the car
position, that is being shared in two different parts of the resulting list structure. When you execute (set-car! (cdr q) 'y)
the x
in the single cell gets replaced by y
in all the parts where it's being shared. Remembering that both (cons 'x null)
cells are really the same, we're going from this:
(cons (cons 'x null) (cons 'x null))
; '((x) x)
to this:
(cons (cons 'y null) (cons 'y null))
; '((y) y)
For the second example the same considerations apply (all three (cons 'x null)
cells are actually the same one being shared), but you're replacing a whole cons
cell, so basically we're going from this:
(cons (cons 'x null) (cons (cons 'x null) (cons 'x null)))
; '((x) (x) x)
to this:
(cons (cons 'x null) (cons 'y (cons 'x null)))
; '((x) y x)
To prove my point that both of the examples in the question demonstrate the same situation, execute this expressions:
(define q2 (mk-q2))
(set-car! (cadr q2) 'y) ; notice the extra `a`
q2
=> '((y) (y) y)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With