set-car! and let in scheme language
lisp, mit-scheme, racket, scheme
Solution
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)
Problem
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?