In the previous lecture, we introduced a more complicated language: we added the notion of a reference to structure, which was itself a value. This was only helpful because we also introduced functions which modify structures: set-[struct]-[field]!. This led to the question "if we make a structure named A, and then define B to be A, and we then modify one of these -- does the other change? (Answer: Yes.) What if we had some other structure that had all the same fields as A -- does that change? (Answer: no.)

This entailed some revisions: make-[struct] actually returns not a structure, but one of these new references -- like a signpost that refers to the actual structure (box with three elements). By having several placeholders that all have a signpost referring to the same object, we can have our program model things the way we think of the world.


Can we write a function, to tell if cats A and B look alike to all external appearances? (Same name, same age, same metabolic status.) Sure.
Even if we modified the cat structure to contain a list of other cats (its pedigree, perhaps) -- that is, do each the cats in A's pedigree should look like the ones in B's pedigree. Sure -- this is reminiscent of xexpr=?. And it is exactly what the built-in equal? does: if each is a simple type (number, symbol, ...) we call the appropriate comparer; if it's a structure (e.g. a cons structure), you recursively call equal? on each part.

However: can we write a function which tells if two cats are identically the same? (To ponder: how to write such a function.) There is a built-in function eq? which does this.

(equal? hyde (make-cat 'bartok 9 true))  = true
(equal? hyde jekyll)                     = true
(eq?    hyde (make-cat 'bartok 9 true))  = false
(eq?    hyde jekyll)                     = true
Not that the name is important, but: things that are merely equal? we call "extensionally" equal (since: if you take either value and "extend" it (compute some result based on its value), you get the same answer).
Things that "identically equal" (a confusing term) we sometimes call "intensionally equal" (note the spelling).

What about structures within structures? Recall from early lectures:

(define-struct brand (type speed seats service))
;;
;; A brand is a structure
;;   (make-brand symbol num num num)
;; where type is the model/make, speed is the cruising speed in mph, 
;; ...

; Examples of the data:
;
(define dc10 (make-brand  'DC-10 550 282 15000))
; ..




(define-struct plane (brand miles mechanic))

;; A plane is a structure
;;    (make-plane brand num symbol)
;; where brand is a brand structure,  miles is ...

; Examples of the data:
;
(define p1 (make-plane dc10  1000 'Joe))
(define p2 (make-plane dc10  500 'Jane))
(define p2 (make-plane (make-brand 'DC-10 550 282 15000)  500 'Jane))
Draw pictures of what's going on here. What if we modify the brand for DC-10?

Recall that lists are just structures.

(define-struct cat (name age high?))
;; a cat is:
;;  (make-cat <symbol> <num> <boolean>)
;; where age is in months.

; Examples:
(define hyde (make-cat 'bartok 9 true))
(define cat2 (make-cat 'freddy-kruger 83 false))

(define clinic-patients (list hyde cat2))

clinic-patients
(set-cat-age! hyde (add1 (cat-age hyde)))
clinic-patients
What does the picture look like, for this?
To do: What is the picture associated with (cons 3 (cons 4 empty))? (Remember that cons should've been called make-cons, to be consistent with other structure constructors.)

What about a structure containing itself -- is this possible? Well, with references, a structure may certainly refer to itself. (May or may not be what we actually intend!)

(define-struct cat (name age high? bestbuddy))
(define hyde (make-cat 'bartok 9 true false))
   ; Hmmm, we don't even have a candidate for hyde's bestbuddy yet.
   ; Use a dummy value, for now.
(define cat2 (make-cat 'freddy-kruger 83 false hyde))

hyde
cat2

(set-cat-bestbuddy! hyde hyde)
;(set-cat-bestbuddy! hyde cat2)

Note that a structure which contains (a reference to) itself might take a long time to difficult to print out. DrScheme takes a bit of care to detect such cycles, and may use shared to print things out.

(shared [(-0- (make-kat 'bartok 
                         9
                         true
                         (make-kat 'freddy-kruger 83 false -0-)))]
    -0-)
"Shared" is much like "local": a declaration of placeholders (here, -0-), and then a single expression. By using those placeholders, it can print values more concisely (at the expense of having placeholders as part of a "value" -- we'd never seen that before, nor needed it). Unlike local, in shared you can define something in terms of itself immediately, for creating circular structures. (Note: shared is an input form, as well as an output form, just like everything else in DrScheme.) We won't make a big deal out of shared -- we'll just use local followed by set-[struct]-[field]!. But don't be intimidated if DrScheme gives back an answer explicitly showing shared data.


The complete code from lecture:
(define-struct cat (name age high?))
;; a cat is:
;;  (make-cat symbol num boolean)
;; where age is in months.

(define hyde (make-cat 'bartok 9 true))
(define cat2 (make-cat 'freddy-kruger 83 false))
(define jekyll hyde)

(equal? hyde (make-cat 'bartok 9 true))
(equal? hyde jekyll)                  
(eq?    hyde (make-cat 'bartok 9 true))
(eq?    hyde jekyll)                   


#|
(define-struct brand (type speed seats service))
(define-struct plane (brand miles mechanic))
;;
;; A brand is a structure
;;   (make-brand symbol num num num)
;; where type is the model/make, speed is the cruising speed in mph, 
;; ...
;; A plane is a structure
;;    (make-plane brand num symbol)
;; where brand is a brand structure,  miles is ...

; Examples of the data:
;
(define dc10 (make-brand  'DC-10 550 282 15000))



; Examples of the data:
;
(define p1 (make-plane dc10  1000 'Joe))
(define p2 (make-plane dc10  500 'Jane))
(define p2 (make-plane (make-brand 'DC-10 550 282 15000)  500 'Jane))
;;; ***  Draw pictures of what's going  on here.
;;; *** What if we modify the brand for DC-10?


; Recall that lists are just structures:
(define clinic-patients (list hyde cat2))
(define animal-control-most-wanted-list 
   (list hyde (make-cat 'bartok 9 true) hyde hyde cat2 hyde))

clinic-patients
animal-control-most-wanted-list
(set-cat-age! hyde (add1 (cat-age hyde)))
clinic-patients
animal-control-most-wanted-list 



; What about a structure containing itself -- is this possible?

(define-struct kat (name age high? bestbuddy))
(define hyde (make-kat 'bartok 9 true false))
   ; Hmmm, we don't even have a candidate for hyde's bestbuddy yet.
   ; Use a dummy value, for now.

(define cat2 (make-kat 'freddy-kruger 83 false hyde))

hyde
cat2

(set-kat-bestbuddy! hyde hyde)
;(set-kat-bestbuddy! hyde cat2)




|#