;; Demonstrates a good use of set! in Scheme, as well as the ;; usefulness of getting assignment and lexical scope right. ;; A fish "class"; i.e., `mk-fish' returns ;; a fish "object" (define (mk-fish size) (lambda (msg) (cond [(eq? msg 'get-size) ; Get size method (lambda () size)] [(eq? msg 'grow) ; Grow method (lambda (amt) (set! size (+ size amt)))] [else (eopl:error 'fish "message not understood")]))) (define fish1 (mk-fish 10)) (define fish2 (mk-fish 20)) ((fish1 'get-size)) ; => 10 ((fish2 'get-size)) ; => 20 ((fish1 'grow) 5) ((fish1 'get-size)) ; => 15 ((fish2 'get-size)) ; => 20 ;; A color-fish subclass (define (mk-color-fish color size) (let ([basic-fish (mk-fish size)]) (lambda (msg) (cond [(eq? msg 'get-color) (lambda () color)] [(eq? msg 'set-color) (lambda (c) (set! color c))] [else (basic-fish msg)])))) (define cfish1 (mk-color-fish 'red 13)) ((cfish1 'get-size)) ; => 13 ((cfish1 'get-color)) ; => 'red ((cfish1 'set-color) 'blue) ((cfish1 'get-color)) ; => 'blue ((cfish1 'grow) 5) ((cfish1 'get-size)) ; => 18