Strukturierungsthema
Definitionen in Racket
Wenn wir Programmierelemente (z.B. Daten, Ausdrücke oder Funktionen) in einem Programm häufig verwenden wollen, kann es Sinn machen diesen einen Namen zuzuordnen um sie nicht bei jeder Nutzung neu erzeugen zu müssen. Dies ist mittels einer Definition möglich.define
gesetzt:
;Definitionen von Daten
(define e 2.71828)
(define willkommenText "Hallo und herzlich willkommen in der funktionalen Programmierung")
;Definitionen von Ausdrücken
(define pi-quadrat (* 3.14159 3.14159))
(define startMessage (string-append "Hallo" "Welt!"))
;Definitionen von bestehenden Funktionen
(define addition +)
(define anzahlZeichen string-length)
Aufgabe 1: Rechnen mit Definitionen
(a) Definiere $\pi$ auf fünf Nachkommastellen genau.
(b) Berechne das Volumen eines Zylinders mit dem Radius 10 cm und der Höhe 20 cm.
$V = r^2 \cdot \pi \cdot h$
(c) Berechne das Volumen einer Kugel mit dem Radius 10 cm.
$V = \frac{4}{3} \cdot \pi \cdot r^3$
Aufgabe 2: Neubennenung von Funktionen durch Definitionen
Neben den Bezeichnungen First-Element und Rest sind auch die Bezeichnungen Head und Tail geläufig. Daher wollen wir in Racket die Möglichkeit schaffen auch diese Bezeichnungen zu nutzen.
(a) Definiere head
und tail
und überprüfe deine Definitionen mit folgenden Ausdrücken:
;Erwartete Rückgabe: 10
> (head (list 10 11 12))
;Erwartete Rückgabe: #<list 11 12>
> (tail (list 10 11 12))
Aufgabe 3: Funktionsdefinition
(a) Im folgenden siehst du zwei Nutzungen vondefine
. Beide werden im Kontext
einer Funktion genutzt.
Erkläre den Unterschied zwischen den Nutzungen.
(define minus -)
(define minus-eins
(lambda (x)
(- x 1)
) )
Aufgabe 3: Definitionsarten in Funktionen
(a) Übertrage die Definition durchmesser
in deine Datei. Definiere anschließend
radius
mit Hilfe eines Ausdruckes der durchmesser
verarbeitet.
(define durchmesser 20)
(b) Übertrage die Funktion volumen-zylinder
in deine Datei.
Wo findest du hier überall Definitionen?
;Berechnet das Volumen eins Zylinders
(: volumen-zylinder (real -> real))
(check-expect (volumen-zylinder radius 20) 6283.18)
(check-expect (volumen-zylinder 6 12) 1357.16688)
(define volumen-zylinder
(lambda (r h)
(define rquad (* r r))
(* rquad (* pi h))
) )
(c) Versuche die Definition rquad
außerhalb der Funktion volumen-zylinder
zu nutzen.
(d) Versuche die Definition rquad
außerhalb der Funktion neu zu definieren. Überprüfe anschließend
die Korrektheit der Funktion volumen-zylinder
mittels der Tests.
(e) Überlege zusammen mit deinem Partner warum es möglich ist, dass in unserem Code zwei verschiedene Definitionen von
rquad
existieren.
(f) Erstelle analog zu (b) eine Funktion volumen-kugel
. Verwende im Funktionskörper mindestens
eine lokale Definition.
Unveränderlichkeit
Wir haben bereits gelernt, dass Definitionen nicht veränderlich sind. Tatsächlich gilt dies in funktionalen Programmiersprachen für alle Daten. Die Unveränderlichkeit (eng. Immutability) stellt somit ein zentrales Konzept in der Funktionalen Programmierung dar. Wenn wir Änderungen an Daten vornehmen (zum Beispiel das hinzufügen eines Elements an eine Liste), werden neue Daten erzeugt, die alten Daten bleiben unverändert.Unveränderlichkeit bedeutet, dass bestehende Daten nicht verändert werden können, sondern bei Änderungen neue Daten erzeugt werden.
Aufgabe 4: Unveränderlichkeit auf Listen
Betrachte die folgenden Ausdrücke. Wie viele Listen werden dabei erzeugt?
Hinweis: Wir definieren eine neu erzeugte Liste als den Rückgabewerte eines einzelnen Ausdrucks.
Der Ausdruck (list 1 2 3)
erzeugt somit nur eine Liste, die inner Struktur der Listenerstellung (die
verschachtelte Verarbeitung innerhalb der Funktion list
) interessiert uns dabei nicht.
(a) Wie viele Listen werden erzeugt?:
(list "Hier" "speichere" "ich" "Strings")
(b) Wie viele Listen werden erzeugt?:
(first (list #t #f #t #t))
(c) Wie viele Listen werden erzeugt?:
(append (list 1 2 3) (list 1 2 3))
(d) Wie viele Listen werden erzeugt?:
(define neueListe (list 3))
(rest (cons "eins" (cons 4.6 neueListe)))