Section #9: =========== 1. Finish with the message-passing things. Add a demonstration of using delegation for inheritance: (define make-2d-point (method (x y) (method (msg) (cond ((= msg get-x:) x) ((= msg get-y:) y) (else: (error "Unknown message passed to point object")))))) (define make-3d-point (method (x y z) (bind ((a-2d-point (make-2d-point x y))) (method (msg) (cond ((= msg get-z:) z) (else: (a-2d-point msg))))))) (define a (make-2d-point 1 2)) (a get-x:) ==> 1 (a get-y:) ==> 2 (a get-z:) ==> {Error : "Unknown message passed to point object"} (define b (make-3d-point 1 2 3)) (b get-z:) ==> 3 (b get-x:) ==> 1 2. Say some things about what data-directed programming (table) - the mechanism that implements generic functions in Dylan. 3. Note - I've tried this: (define-generic-function f ((x ))) (add-method f (method ((x )) 3)) And it looks like define-generic-function with type specification means that we can only use this generic function with these types of arguments, e.g: (f 4) ==> 3 (f "f") ==> {Error : Object "f" failed type constraint {Class (21)}. 4. Another note - (singleton x) builds a 'type' (a class) that contains exactly one instance which is x itself. Show examples. 5. An OOP example: Here is a simple class definition: (define-class () (name "anonymous") (strength )) (define animal (make )) So we have a default value for the name slot: (name animal) ==> "anonymous" But no default for strength: (strength animal) ==> {Error : "Attempt to get value of uninitialized slot."} A subclass of is a : (define-class () (name "snoopy") (strength 10)) That defines the initialization of the strength slot to be 10 and overrides the initialization of name to "snoopy": (define dog (make )) (name dog) ==> "snoopy" (strength dog) ==> 10 Add a weaker-by-default class: (define-class () (name "garfield") (strength 5)) (define cat (make )) Define a generic function: (define-generic-function fight (animal1 animal2)) (add-method fight (method ((a1 ) (a2 )) (print (name a1) " and " (name a2) " are having a fight!") (cond ((> (strength a1) (strength a2)) (print (name a1) " won!!!") a1) ((> (strength a2) (strength a1)) (print (name a2) " won!!!") a2) ((> (strength a2) (strength a1)) (print "Neither won...") #f)))) (fight cat dog) garfield and snoopy are having a fight! snoopy won!!! ==> {Instance of {Class (2)}} However, in our fictive reality, when cats fights dogs, they always win: (add-method fight (method ((a1 ) (a2 )) (print (name a1) " and " (name a2) " are having a fight!") (print (name a1) " won!!!") a1)) (fight cat dog) garfield and snoopy are having a fight! garfield won!!! ==> {Instance of {Class (3)}} But: (fight dog cat) snoopy and garfield are having a fight! snoopy won!!! ==> {Instance of {Class (2)}} So this fixes things, in an ugly way: (add-method fight (method ((a1 ) (a2 )) (fight a2 a1))) (fight dog cat) garfield and snoopy are having a fight! garfield won!!! ==> {Instance of {Class (3)}}