;; Die ersten drei Zeilen dieser Datei wurden von DrScheme eingefügt. Sie enthalten Metadaten ;; über die Sprachebene dieser Datei in einer Form, die DrScheme verarbeiten kann. #reader(lib "DMdA-assignments-reader.ss" "deinprogramm")((modname kapitel-13d) (read-case-sensitive #f) (teachpacks ()) (deinprogramm-settings #(#f write repeating-decimal #t #t none explicit #f ()))) ; Kapitel 13 ; Mixins ; Liste von Zeichenketten in der REPL ausdrucken (: write-list-newline ((list string) -> unspecific)) (define write-list-newline (lambda (lis) (begin (for-each (lambda (s) (write-string s)) lis) (write-newline)))) ; Nachrichten sind Zeichenketten (define message (contract string)) ; Prozedur mit unbekanntem Vertrag (define method (contract %a)) ; Person konstruieren ; make-person : string -> (message -> method) (define make-person (lambda (name) (let ((slaps 0)) (lambda (message) (cond ((equal? message "get-name") ;; person -> string (lambda (self) name)) ((equal? message "say") ;; person list(string) -> unspecified (lambda (self stuff) (write-list-newline stuff))) ((equal? message "slap") ;; person -> unspecified (lambda (self) (begin (set! slaps (+ 1 slaps)) (if (< slaps 3) (send self "say" (list "huh?")) (begin (send self "say" (list "ouch!")) (set! slaps 0)))))) (else #f)))))) ; Nachricht an Objekt senden und entsprechende Methode aufrufen ; send : object string ... -> ... (define send (lambda (object message . args) (apply (object message) (make-pair object args)))) ; Sänger(in) konstruieren ; make-singer : string -> (message -> method) (define make-singer (lambda (name) (let ((person (make-person name))) (lambda (message) (cond ((equal? message "sing") ;; Text singen ;; singer list(string) -> unspecified (lambda (self stuff) (send self "say" (make-pair "tra-la-la " stuff)))) (else (person message))))))) ; Dichter konstruieren ; make-poet : string -> (message -> method) (define make-poet (lambda (name) (lambda (message) (cond ((equal? message "say") ;; poet list(string) -> unspecified (lambda (self stuff) (write-list-newline (append stuff (list " and the sky is blue"))))) ((equal? message "recite") ;; poet -> unspecified (lambda (self) (write-list-newline (list "the sky is blue")))) (else #f))))) ; zu einer Klasse Coolness hinzufügen ; make-make-cool-someone : ; (string-> (message -> method)) -> (string -> (message -> method)) (define make-make-cool-someone (lambda (make-someone) (lambda (name) (let ((someone (make-someone name))) (lambda (message) (cond ((equal? message "say") ;; Text aufsagen ;; cool-someone list(string) -> unspecified (lambda (self stuff) (send someone "say" (append stuff (list ", dude"))))) ((equal? message "slap") ;; ohrfeigen ;; cool-someone -> unspecified (lambda (self) (send self "say" (list "pain just makes me stronger")))) (else (someone message)))))))) ; make-rock-star : string -> (message -> method) (define make-rock-star (make-make-cool-someone make-singer)) (define slash (make-rock-star "Slash")) (send slash "sing" (list "oh yeah")) ; make-cool-poet : string -> (message -> method) (define make-cool-poet (make-make-cool-someone make-poet)) (define charles (make-cool-poet "Charles")) (send charles "say" (list "hello"))