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 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) = trueNot 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).
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-patientsWhat does the picture look like, for this?
(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.
(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) |#