;;; Konstruktion, Vorlesung vom 31.10.2000 ;;; K5 Einfache Datenstrukturen ; Datentyp "posn" ; Koordinaten von Pixeln auf den Bildschirm ; Paar von Zahlen: (make-posn x y) (make-posn 1 2) (define p1 (make-posn 4 5)) ; Zugriff auf die Komponenten (posn-x p1) (posn-y p1) ; SIGNATUR ; distance-to-0 : posn -> number ; ERKLÄRUNG ; (distance-to-0 posn) = Abstand zum Koordinatenursprung ; BEISPIELE ; (distance-to-0 (make-posn 0 10)) = 10 ; (distance-to-0 (make-posn 3 4)) = 5 ; (distance-to-0 (make-posn 10 10)) = 14.24... = (* 10 (sqrt 2)) ; DEFINITION (define distance-to-0 (lambda (p) (sqrt (+ (square (posn-x p)) (square (posn-y p)))))) ; Definition von Datenstrukturen ;(define-struct posn (x y)) ; Ein "posn" ist eine Struktur (make-posn x y), ; wobei x : number und y : number ; definiert ; 1. den KONSTRUKTOR make-posn : number number -> posn ; 2. den SELEKTOR posn-x : posn -> number ; 3. den SELEKTOR posn-y : posn -> number ; (vordefiniert in DrScheme) ; DEFINITION (Erweiterung von Def K1) ; Der Wert von (make-posn e1 e2) ist (make-posn v1 v2), ; falls v1 der Wert von e1 und v2 der Wert von e2 ist. ; Der Wert von (posn-x e) wird ermittelt, indem zuerst der Wert ; v von e ermittelt wird. ; Falls v == (make-posn v1 v2), dann ist v1 das Ergebnis. ; Weitere Datenstrukturen (define-struct circle (origin radius)) ; Ein "circle" ist eine Struktur (make-circle origin radius) ; wobei origin : posn und radius : number. ; Bezeichnet einen Kreis mit Mittelpunkt origin und Radius radius. ; SIGNATUR ; circle-area : circle -> number ; ERKLÄRUNG ; (circle-area c) berechnet die Fläche von c ; BEISPIEL ; (circle-area (make-circle (make-posn 0 0) 2)) == 4 * pi ; DEFINITION (define circle-area (lambda (c) (* pi (square (circle-radius c))))) (define-struct rectangle (origin extent)) ; Ein "rectangle" ist eine Struktur (make-rectangle origin extent) ; wobei origin, extent : posn. ; Bezeichnet ein Rechteck mit linkem unteren Rand origin, ; Breite (posn-x extent) und Höhe (posn-y extent). ; SIGNATUR ; rectangle-area : rectangle -> number ; ERKLÄRUNG ; (rectangle-area r) berechnet die Fläche von r ; BEISPIEL ; (rectangle-area ; (make-rectangle (make-posn 0 0) (make-posn 2 2)) == 4 ; DEFINITION (define rectangle-area (lambda (r) (* (posn-x (rectangle-extent r)) (posn-y (rectangle-extent r))))) ; Wiederholte Berechnung von (rectangle-extent r) ; Vermeiden durch Bindung an Variable ; ::= (let (( )* ) ) (define rectangle-area (lambda (r) (let ((extent (rectangle-extent r))) (* (posn-x extent) (posn-y extent))))) ; DEFINITION (Erweiterung von Def K1) ; Der Wert von (let ((x1 e1) ... (xn en)) e) wird ermittelt, indem ; zunächst die Werte v1 (von e1) bis vn (von en) ermittelt ; werden. Der Wert von (let ((x1 v1) ... (xn vn)) e) ist genau der ; Wert von e nach Ersetzung von x1 durch v1 ... xn durch vn. ; Das heisst: ; (let ((x1 e1) ... (xn en)) e) ; == ; ((lambda (x1 ... xn) e) e1 ... en) ; (let ((x1 e1) ... (xn en)) e) funktioniert nicht sequentiell! ; Weitere Abkürzung: ; (let* ((x1 e1) ... (xn en)) e) ; == ; (let ((x1 e1)) ; (let ((x2 e2)) ; ... ; (let ((xn en)) ; e)...)) ; (let* ((x1 e1) ... (xn en)) e) funktioniert sequentiell! ; SIGNATUR ; posn-move : posn posn -> posn ; ERKLÄRUNG ; (posn-move p d) verschiebt p um d ; DEFINITION (define posn-move (lambda (p d) (make-posn (+ (posn-x p) (posn-x d)) (+ (posn-y p) (posn-y d))))) ; SIGNATUR ; circle-move : circle posn -> circle ; ERKLÄRUNG ; (circle-move c p) erzeugt eine Kopie vom Kreis c, dessen Ursprung um ; p verschoben ist. ; BEISPIEL ; (circle-move (make-circle (make-posn 1 2) 4) (make-posn -1 -1)) ; => (make-circle (make-posn 0 1) 4) ; DEFINITION (define circle-move (lambda (c p) (make-circle (posn-move (circle-origin c) p) (circle-radius c)))) ; SIGNATUR ; rectangle-move : rectangle posn -> rectangle ; ERKLÄRUNG ; (rectangle-move r p) erzeugt eine Kopie von r, dessen linke untere ; Ecke um p verschoben ist. ; BEISPIEL ; (rectangle-move (make-rectangle (make-posn 1 2) (make-posn 3 4)) ; (make-posn -1 -1)) ; => (make-rectangle (make-posn 0 1) (make-posn 3 4)) ; DEFINITION (define rectangle-move (lambda (r p) (make-rectangle (posn-move (rectangle-origin r) p) (rectangle-extent r)))) ;;; Zusammenfassung ;;; Syntax ; ::= (define-struct (*)) ; ; (define-struct (y1 ... yn)) ; definiert ; KONSTRUKTOR (make- y1 ... yn) ; SELEKTOREN (-y1 e) ... (-yn e) (define-struct line (origin extent)) ; Eine "line" ist eine Struktur (make-line p1 p2), ; wobei p1, p2 : posn. ; Repräsentiert eine Linie von p1 nach p1 + p2. ; SIGNATUR ; line-area : line -> number ; ERKLÄRUNG ; Flächeninhalt einer Linie (immer 0) ; DEFINITION (define line-area (lambda (l) 0)) ; SIGNATUR ; line-move : line posn -> line ; ERKLÄRUNG ; verschiebt den Ursprung der "line" um "posn" ; BEISPIEL ; (line-move (make-line (make-posn 1 1) (make-posn 3 3)) ; (make-posn 2 0)) ; == (make-line (make-posn 3 1) (make-posn 3 3)) ; DEFINITION (define line-move (lambda (l d) (make-line (posn-move (line-origin l) d) (line-extent l))))