Some remedial semantics while I'm feeling sick as a dog...

What's happening in this program?

(define x (cons 'a 'b))

(define y (cons 'c 'd))

(define z (cons x y))

(set-car! z y)

(set-car! y 'e)

z

; => ((e . d) e . d)

First remember that

expressed values are the values the expressions can evaluate to, and

denoted values are the values that are stored in environments--in Scheme, denoted values are locations in the store, and expressed values include mutable pairs, which are pairs of store locations.

Let's be the interpreter. After the first two definitions, we have the following configuration:

env: [x -> 2][y -> 5]

store:

0 : 'a

1 : 'b

2 : (0, 1)

3 : 'c

4 : 'd

5 : (3, 4)

Next we define the pair

(cons x y). The evaluation of x and y gives us expressed values

(0, 1) and

(3, 4). Evaluation of the

cons duplicates these pair values, and the new pair points to these two new copies:

env: [x -> 2][y -> 5][z -> 8]

store:

0 : 'a

1 : 'b

2 : (0, 1)

3 : 'c

4 : 'd

5 : (3, 4)

6 : (0, 1)

7 : (3, 4)

8 : (6, 7)

Now, for the first

set-car!, the first argument evaluates to the pair associated with z, i.e., the expressed value

(6, 7). The second argument evaluates to the expressed value

(3, 4). Because the pair is really a pair of pointers, we don't touch its value but rather change the value in the cell

pointed to by the

car of the pair, i.e. cell 6:

0 : 'a

1 : 'b

2 : (0, 1)

3 : 'c

4 : 'd

5 : (3, 4)

6 : (3, 4)

7 : (3, 4)

8 : (6, 7)

Now the second

set-car! evaluates its first argument to the pair

(3, 4) and again mutates the cell pointed to by the

car of the pair:

0 : 'a

1 : 'b

2 : (0, 1)

3 : 'e

4 : 'd

5 : (3, 4)

6 : (3, 4)

7 : (3, 4)

8 : (6, 7)

By the end, we have multiple copies of y, but they all point to the same location 3, which has been mutated.

My kingdom for ref-cells!