Let's recap.  The previous lecture studied set-structure!.  We can
reason about set-structure! the same way that we reason about set!: by
erasing and replacing values used when a structure was created.
However, structure updates can take effect across function calls and
we have to be careful about sharing them.

Recall the add-child-name! program that we wrote in the last class.

;; A person is a structure
;;  (make-person N F M C)
;; where N is a symbol,
;;       F and M are person or false, and
;;       C is (listof person)

(define-struct person (name father mother children))

;; add-child-name! : symbol person person -> person
;; creates a node for a child, adds it to the tree, and returns the new node
;; effect : adds a new child node to the list of children in father and mother
(local [(define child-node (make-person name father mother empty))]
(set-person-children! father (cons child-node (person-children father)))
(set-person-children! mother (cons child-node (person-children mother)))
child-node))

Could we have written this program without using set-structure!?  No,
because the child and the father each need to refer to each other, and
we have to create one of them first (same for mother).

Could we have also written the program as follows?

(set-person-children!
father (cons (make-person name father mother empty)
(person-children father)))
(set-person-children!
mother (cons (make-person name father mother empty)
(person-children mother)))
(first (person-children mother)))

Let's try it out.

> (define bob (make-person 'bob false false empty))
> (define ann (make-person 'ann false false empty))
> (define susan (add-child-name! 'susan bob ann))
> susan
(shared ((-0- (make-person 'susan -1- -4- empty))
(-1-
(make-person
'bob
false
false
(list (make-person 'susan -1- -4- empty))))
(-4- (make-person 'ann false false (list -0-))))
-0-)
> (define tom (make-person 'tom false false empty))
(shared ((-0- (make-person 'liz -1- -9- empty))
(-1-
(make-person 'susan -2- -5- (list (make-person 'liz -1- -9- empty))))
(-2-
(make-person
'bob
false
false
(list (make-person 'susan -2- -5- empty))))
(-5- (make-person 'ann false false (list -1-)))
(-9- (make-person 'tom false false (list -0-))))
-0-)

Do you see the problem here?  We have two different nodes for susan in
the tree.  One (-1-) shows a child named liz.  The other (inside the
record for bob) shows no such child.  This is clearly a problem.  Once
you write programs that changes values in structures, you must be very
careful to share structures exactly when necessary for your program.
This is a case where not sharing causes a problem.  There are other
cases where unexpected sharing is a problem.

We've now seen two ways to update a structure: we can create a new
structure, or we can use set-structure!.  How do we choose between
these methods?  As a general rule, update a structure only if the
structure represents a persistent object and your program corresponds
to a real action.  For example, address books are persistent objects
to make.  In contrast, imagine that you were writing a program to play
chess and you wanted to see what would happen if you took a particular
move.  You should not use a set-structure! to change the move because
you haven't yet decided to take that move (it's a preliminary, not a
real, action).

In the last class, there was a question regarding how to alter the
contents of a list.  As we showed early in the course, we can think of
a list as a structure containing two fields, a first and a rest.
Therefore, we should be able to change the first and rest components
of a list using something similar to set-structure!  The operators
that you need are called set-car! (to change the first) and set-cdr!
(to change the rest).  Here are some examples:

> (define lst (list 1 2 3 4))
> lst
(list 1 2 3 4)
> (set-car! lst 5)
> lst
(list 5 2 3 4)
> (set-car! (rest lst) 7)
> lst
(list 5 7 3 4)
> (set-cdr! lst empty)
> lst
(list 5)
> (set-cdr! lst 3)
set-cdr!: second argument must be of type , given (list 5) and 3

set-car! and set-cdr! are like set-structure! in that they have effect
across function boundaries:

> (define (f lst)
(set-car! lst 5))
> (define l1 (list 1 2 3 4))
> l1
(list 1 2 3 4)
> (f l1)
> l1
(list 5 2 3 4)

Studying the effects of set! and set-structure! (which includes
are two structures or two lists the same?  Consider the following two
structures:

(make-entry 'kathi 3)
(make-entry 'kathi 3)

Are these two structures the same?  It depends on what we mean by "the
same".  Certainly, they have the same contents; in one sense
therefore, they are the same.  But are they the same structure?  Let's
ask DrScheme.  Scheme provides an operator eq? to test whether two
arbitrary values are the same:

> (eq? 4 4)
true
> (eq? 'a 'a)
true
> (eq? 'a 'A)
false
> (eq? 4 'a)
false

Thus, eq? is more general than either = or symbol=?, which require
their arguments to be of the appropriate type.

> (define-struct entry (name phone))
> (eq? (make-entry 'kathi 3) (make-entry 'kathi 3))
false

Thus, DrScheme says that

(make-entry 'kathi 3)	and	(make-entry 'kathi 3)

are not the same values.  Is there a way to ask DrScheme whether two
structures have the same contents?  Yes, it's called equal?

> (equal? (make-entry 'kathi 3) (make-entry 'kathi 3))
true

Intuitively, the difference between eq? and equal? is that eq? asks
whether two values were created at the same time and equal? asks
whether two values have the same structure.  Here are some more
examples:

> (eq? (list 1 2) (list 1 2))
false
> (equal? (list 1 2) (list 1 2))
true
> (equal? (list 1 2) (list 2 1))
false
> (define-struct entry (name phone))
> (equal? (list (make-entry 'kathi 3))
(list (make-entry 'kathi 3)))
true

Unfortunately, our current distinction between eq? and equal? relies
on intuition.  In order to explain this difference more precisely, we
have to get under the hood a bit to see how Scheme manages variables
and structured values.