Funktionsdefinition Schritt 4: Funktionsgerüst
Gerüst einer Funktion
In Schritten 1 bis 3 haben wir uns also mit der Modellierung der Funktion beschäftigt und diese in den Code eingebettet. Noch haben wir jedoch keine Funktion die wir tatsächlich aufrufen können. Hierfür entwerfen wir ein Gerüst.
Betrachten wir wieder unsere gewünschte Funktion als BlackBox-Diagramm:;Berechnet den flaecheninhalt eines Quaders in mm
(: flaecheninhalt (natural natural -> natural))
(check-expect (flaecheninhalt 125 20) 2500)
(check-expect (flaecheninhalt 125 0) 0)
Wir sehen anhand der Modellierungen unter anderem, dass die Funktion zwei Übergabebedaten übergeben bekommt. Unklar ist
jedoch noch, wie wir diese Übergabedaten in der Funktion überhaupt verwenden können und wie wir die Funktion tatsächlich aufrufbar
machen.
In Racket gibt es hierfür zwei Schlüsselwörter, die wir für unsere Funktionsdefinition verwenden: define
und lambda.Schlüsselwort lambda
Aufgabe 1. Funktionsweise des Schlüsselworts lambda
Führe die folgenden Zeilen in der REPL aus. Kannst du dir die Ergebnisse erklären? Analysiere hierzu die einzelnen Ausdrücke. Achte dabei besonders auf die Klammerungen innerhalb der Ausdrücke.
> ((lambda (x) (+ x x)) 3)
> ((lambda (x) (* x x)) 3)
> ((lambda (x y) (+ x y)) 2 3)
> ((lambda (x y) (* (+ x y) y) 2 3)
Tipp: Schau dir gerne auch die Hilfestellung unter dieser Aufgabe an.
Hilfestellung zum Lambda-Ausdruck
Wir können uns Lambda als eine Funktion vorstellen, die eine beliebige Anzahl von
Übergabebedaten erhält. Diese Übergabebedaten bekommen innerhalb von Lambda einen Namen.
In der linken Abbildung erhält Lambda beispielsweise eine Übergabebedatum, welches den Namen $x$ erhält.
In der rechten Abbildung erhält Lambda zwei Übergabebedaten, welche die Namen $x$ und $y$ erhalten.
In Racket wäre dies entsprechend:
(lambda (x) ...) ;links
(lambda (x y) ...) ;rechts
;... fungieren als Platzhalter
Innerhalb von Lambda können Ausdrücke stehen, die die Namen der Übergabebedaten wiederverwenden.
In unserem Beispiel die Ausdrücke $(+\ x\ x\ )$ links und $(*\ (+\ x\ y)\ y)$ rechts.
Bzw. in Racket:
(lambda (x) (+ x x)) ;links
(lambda (x y) (* (+ x y) y)) ;rechts
Diese Ausdrücke, können wir dann wie gewohnt mit passenden Werten für die Übergabebedaten aufrufen.
((lambda (x) (+ x x)) 3) ;links
((lambda (x y) (* (+ x y) y)) 2 3) ;rechts

Exkurs: Warum heißt das Schlüsselwort "lambda"?
Die Verwendung des griechischen Buchstaben lambda ($\lambda$) stammt aus dem mathematisch/informatischen $\lambda$-Kalkül. Hierzu in einem späteren Kapitel mehr.
Namensgebung der Übergabebedaten
Natürlich müssen die Namen nicht $x$ oder $y$ sein. Wir könnten also beispielsweise auch ein Lambda-Ausdruck wie folgt nennen: ((lambda (summand1 summand2) (+ summand1 summand2)) 20 22)
Schlüsselwort define
Aufgabe 2. Funktionsweise des Schlüsselwort define
Führe die Ausdrücke, nacheinander in der REPL aus. Welchen Zweck erfüllt das Schlüsselwort define?
> (+ 2 vier)
> (define vier 4)
> (+ 2 vier)
> (addition 2 4)
> (define addition +)
> (addition 2 4)
> (anzahlZeichen "Hallo")
> (define anzahlZeichen string-length)
> (anzahlZeichen "Hallo")
> (addition (anzahlZeichen "Ich") vier)
Aufgabe 3. Ändern von Definitionen
Was erwartest du wenn du die beiden unteren Ausdrücke in der REPL ausführst? Führe die Ausdrücke, nacheinander in der REPL aus und überprüfe deine Vermutung.
> (define lieblingszahl 42)
> (define lieblingszahl 17)
Das Gerüst - mit define und lambda
Um nun unser Gerüst für die Flächeninhaltsberechnung zu erstellen, kombinieren wir die Schlüsselwörter define und lambda. Hierzu geben wir einem Lambda-Ausdruck einfach einen Namen nach dem Prinzip:
(define nameFunktion
(lambda (parameter1 ... parameterN)
...))
Diese Zeilen nennen wir das Gerüst einer Funktion.
Zusammenhang Signatur und Gerüst der Funktion
Auch bei der Erstellung des Gerüsts ist unsere vorangegangene Modellierung hilfreich.
Aufgabe 4. Zusammenhang Signatur und Gerüst
In der Signatur einer Funktion, stecken bereits zentrale Informationen, die wir für unsere Gerüst mit define und lambda verwenden können.
Vergleiche die Signatur und das Gerüst der drei Funktionen. Welche Parallelen kannst du feststellen?
a)
;Halbiert eine natürliche Zahl
(: halbieren (natural -> rational))
(check-expect (halbieren 4) 2)
(check-expect (halbieren 9) 4.5)
(define halbieren
(lambda (zahl)
...))
b)
;Berechnet die Summe der Zeichen zweier Zeichenketten
(: summeZweierZeichenketten (string string -> natural))
(check-expect (summeZweierZeichenketten "Hallo" "Welt") 9)
(check-expect (summeZweierZeichenketten "Informatik ist cool" "") 19)
(define summeZweierZeichenketten
(lambda (wort1 wort2)
...))
c)
;Berechnet das Produkt dreier Zahlen
(: produktDreiZahlen (real real real -> real))
(check-expect (produktDreiZahlen 12 10 0) 0)
(check-expect (produktDreiZahlen 5 7.6 -14.1) -535.8)
(define produktDreiZahlen
(lambda (x y z)
...))
2. Die Anzahl an Parametern von lambda, muss exakt der Anzahl der Übergabebedaten entsprechen.
Aufgabe 5. Gerüst der Flächeninhaltsberechnung
Schreibe in dein Definitionsfenster unter deine Testfälle das Gerüst für unsere Flächeninhaltsberechnung. Denke dir dabei geeignete Namen für die Übergabebedaten aus.
Übungsaufgaben
Aufgabe 6. Erstellen von geeigneten Gerüsten
Schreibe in dein Definitionsfenster das Gerüst unter deine Testfälle der Modellierungen folgender Funktionen: (Aufgabe 3. und 4. im vorangegangenen Kapitel)
- Die Funktion quadrieren
- Die Funktion korrekteAnzahlBuchstaben?
- Der Funktion die den Durchschnitt zweier ganzer Zahlen berechnen soll.
- Der Funktion die bestimmt, ob ein Text eine gerade Anzahl an Buchstaben hat.