;; 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-13c) (read-case-sensitive #f) (teachpacks ()) (deinprogramm-settings #(#f write repeating-decimal #t #t none explicit #f ()))) ; Kapitel 13 ; Objekte mit neuem self ; 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))))))) ; Rock-Star konstruieren ; make-rock-star : string -> (message -> method) (define make-rock-star (lambda (name) (let ((singer (make-singer name))) (lambda (message) (cond ((equal? message "say") ;; Text aufsagen ;; rock-star list(string) -> unspecified (lambda (self stuff) (send singer "say" (append stuff (list ", dude"))))) ;; ohrfeigen ;; rock-star -> unspecified ((equal? message "slap") (lambda (self) (send self "say" (list "pain just makes me stronger")))) (else (singer message))))))) (define slash (make-rock-star "Slash")) (send slash "say" (list "hello")) (send slash "slap") (send slash "sing" (list "oh yeah")) ; 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))))) (define johann (make-poet "Johann")) (send johann "say" (list "hello")) ; Axl ; axl : message -> method (define axl (let ((rock-star (make-rock-star "Axl")) (poet (make-poet "Axl"))) (lambda (message) (let ((rock-star-method (rock-star message))) (if (equal? rock-star-method #f) (poet message) rock-star-method))))) (send axl "say" (list "hello")) (send axl "recite") (define henry (let ((poet (make-poet "Henry")) (rock-star (make-rock-star "Henry"))) (lambda (message) (let ((poet-method (poet message))) (if (equal? poet-method #f) (rock-star message) poet-method))))) (send henry "say" (list "hello")) (send henry "slap")