Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick...

110
Funktionale Programmierung Klaus Becker 2007

Transcript of Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick...

Page 1: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

Funktionale Programmierung

Klaus Becker

2007

Page 2: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

2 Programmieren mit Funktionen

Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen verstehen Grundkonzepte kennen lernen Relevanz anhand von Miniprojekten erkennen

Mit Funktionen kann man programmieren. Die Programme bestehen aus Funktionsdeklarationen. Funktionsdeklarationen werden mit Hilfe von Funktionskomposition, Fallunterscheidungen undRekursion aufgebaut. ...

Page 3: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

3 Teil 1

Von der Registermaschine zur funktionalen Abstraktion

Page 4: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

4 Registermaschine

Eine Registermaschine bearbeitet beliebig eingebbare Daten nach einem fest vorgegebenen Programm.

> x INC i Erhöhe Register i um 1. Gehe zu Zeile x+1.

> x DEC i Erniedrige Register i um 1. Gehe zu Zeile x+1.

> x JMP i Gehe zu Zeile i.

> x TST iWenn Register i ungleich 0 ist, dann gehe zu Zeile x+1, sonst zu Zeile x+2.

> x HLT Beende die Bearbeitung.

> 1 JMP 4 2 INC 1 3 DEC 2 4 TST 2 5 JMP 2 6 HLT

1: 52: 33: 04: 05: 0..

ProgrammDaten

Page 5: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

5 Aufgabe

Was leistet das unten abgebildete Registermaschinenprogramm? Messen Sie die Zeit, die Sie brauchen, um das herauszufinden.

1 TST 22 JMP 43 JMP 74 TST 35 JMP 136 JMP 107 TST 38 JMP 199 HLT10 TST 211 JMP 1712 HLT 13 DEC 214 DEC 315 INC 116 JMP 117 DEC 218 JMP 1019 DEC 320 JMP 7

Page 6: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

6 Aufgabe

Was leistet das unten abgebildete (Python-) Programm? Messen Sie die Zeit, die Sie brauchen, um das herauszufinden.

while (R2 <> 0) and (R3 <> 0): R1 = R1 + 1 R2 = R2 - 1 R3 = R3 - 1while R2 <> 0: R2 = R2 - 1while R3 <> 0: R3 = R3 -1

Page 7: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

7

Spaghetti-Code mit Sprunganweisungen

Durch die vielen Sprunganweisungen verliert man leicht den Überblick über die Ablauflogik.

Wer strukturiert programmiert, verzichtet auf solche Sprunganweisungen, auch wenn die Programmiersprache sie zur Verfügung stellt.

Viele Programmiersprachen stellen keine Sprunganweisungen zur Verfügung. Dann können solch schwer zu durchschauenden Programme gar nicht erst geschrieben werden.

"Spaghetti-Code"

1 TST 22 JMP 43 JMP 74 TST 35 JMP 136 JMP 107 TST 38 JMP 199 HLT10 TST 211 JMP 1712 HLT 13 DEC 214 DEC 315 INC 116 JMP 117 DEC 218 JMP 1019 DEC 320 JMP 7

Page 8: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

8

Ablaufkontrolle mit Kontrollanweisungen

An Stelle von Sprunganweisungen benutzt man Kontrollstrukturen, um die Ablauflogik strukturiert zu beschreiben.

while (R2 <> 0) and (R3 <> 0): R1 = R1 + 1 R2 = R2 - 1 R3 = R3 - 1while R2 <> 0: R2 = R2 - 1while R3 <> 0: R3 = R3 -1

1 TST 22 JMP 43 JMP 74 TST 35 JMP 136 JMP 107 TST 38 JMP 199 HLT10 TST 211 JMP 1712 HLT 13 DEC 214 DEC 315 INC 116 JMP 117 DEC 218 JMP 1019 DEC 320 JMP 7 Ablaufbeschreibung mit

Sprunganweisungen

Ablaufbeschreibung mit Kontrollstrukturen

Page 9: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

9 Aufgabe

Vergleichen Sie die beiden Programme. Welche Version ist besser?

def minimum(a, b): m = 0 while (a <> 0) and (b <> 0): m = m + 1 a = a - 1 b = b - 1 return m

def minimum(a, b): global m while (a <> 0) and (b <> 0): m = m + 1 a = a - 1 b = b - 1

>>> minimum(5, 7)5

>>> m = 0>>> minimum(5, 7)>>> m5

Page 10: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

10 Seiteneffekte

Das Unterprogramm auf der linken Seite verändert den Wert einer globalen Variablen. Das Unterprogramm hat einen sog. Seiteneffekt.

def minimum(a, b): m = 0 while (a <> 0) and (b <> 0): m = m + 1 a = a - 1 b = b - 1 return m

def minimum(a, b): global m while (a <> 0) and (b <> 0): m = m + 1 a = a - 1 b = b - 1

>>> minimum(5, 7)5

>>> m = 3>>> minimum(5, 7)>>> m8>>> m = 0>>> minimum(5, 7)>>> m5

Unterprogramm mit Seiteneffekt

Page 11: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

11 Programme ohne Seiteneffekte

Eine Funktion soll normalerweise aus den Argumenten einen Wert berechnen und nichts anderes nebenbei tun. Von diesem Prinzip weichen Programmierer jedoch immer wieder ab, etwa indem sie in der Funktion globale Variablen verändern. Wer strukturiert programmiert, verzichtet auf Seiteneffekte.

Es gibt Programmiersprachen, die keine Seiteneffekte zulassen. Die Idee dabei ist, auf Wertzuweisungen zu verzichten, so dass keine unbeabsichtigten Seiteneffekte möglich sind.

def minimum(a, b): if a == 0: return a else: if b == 0: return b else: return 1 + minimum(a-1, b-1)

Unterprogramm ohne Wertzuweisung

Page 12: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

12 Zielsetzung

Ziel ist es, die Grundideen funktionaler Programmierung anhand von Beispielen problemorientiert zu erarbeiten. Insbesondere soll dabei herausgearbeitet werden, dass Programmierung ohne Wertzuweisungen möglich ist.

Page 13: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

13 Teil 2

Konzepte der funktionalen Programmierung

Page 14: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

14 Fallstudie: Chiffrieren

Ziel ist es, Chiffrierverfahren (die auf modularem Rechnen basieren), mit Hilfe funktionaler Programme zu beschreiben.

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

D E F G H I J K L M N O P Q R S T U V W X Y Z A B C

Schlüssel: DQuelltext:

SALVECAESAR

Geheimtext:VDOYHFDHVDU

PYLZFOWBNQCYBUVNCBLGYCHYAYBYCGMWBLCZNYH

NTCZYLN

VDOYHFDHVD

U

Page 15: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

15 Additives Chiffrierverfahren

Codierung:

Code: A → 1Blocklänge: 2

AA → 0101AB → 0102

...ZZ → 2626

AS#TE#RI#X

0119#2005#1809#24

Verschlüsselung:

öffentlicher Schlüssel(d, m) = (2102, 3000)

z → (z + d) % m 0119#2005#1809#24

2221#1107#1010#2126

Entschlüsselung:

privater Schlüssel(e, m) = (898, 3000)

z → (z + e) % m 2221#1107#1010#2126

0119#2005#1809#24

Decodierung:

Code: A → 1Blocklänge: 2

AA → 0101AB → 0102

...ZZ → 2626

0119#2005#1809#24

AS#TE#RI#X

Bed.: z < mm > maxCode

Bed.: (d + e) % m = 0

Page 16: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

16 Additives Chiffrierverfahren

Wir betrachten zunächst das Verschlüsseln und Entschlüsseln von Zahlenfolgen mit Schlüsseln, die aus zwei Komponenten bestehen. Da Ver- und Entschlüsseln gleich funktionieren, reicht es, nur das Verschlüsseln zu betrachten.

Verschlüsselung:

öffentlicher Schlüssel(d, m) = (2102, 3000)

z → (z + d) % m 0119#2005#1809#24

2221#1107#1010#2126

Entschlüsselung:

privater Schlüssel(e, m) = (898, 3000)

z → (z + e) % m 2221#1107#1010#2126

0119#2005#1809#24

Bed.: m ist größer als die maximale Codezahl

Bed.: d + e = m

Page 17: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

17 Funktionale Modellierung

verschluesselnZahl

Eingaben:zahl: die zu verschlüsselnde Zahlschluessel: Zahlenpaar bestehend aus der zu addierenden Konstante und dem Divisionsmodul

Ausgabe:die berechnete verschlüsselte Zahl

(2102, 3000) 2221

119

Spezifikation:

schluessel

zahl

Verschlüsselung:

öffentlicher Schlüssel(d, m) = (2102, 3000)

z → (z + d) % m 0119#2005#1809#24

2221#1107#1010#2126Bed.: z < mm > maxCode

Page 18: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

18 Funktionale Modellierung

verschluesseln

Eingaben:zahlenListe: Liste mit den zu verschlüsselnden Zahlenschluessel: Zahlenpaar bestehend aus der zu addierenden Konstante und dem Divisionsmodul

Ausgabe:Liste mit den berechneten verschlüsselten Zahlen

(2102, 3000) [2221, 1107, 1010, 2126]

[119, 2005, 1809, 24]

Spezifikation:

schluessel

zahlenListe

Verschlüsselung:

öffentlicher Schlüssel(d, m) = (2102, 3000)

z → (z + d) % m 0119#2005#1809#24

2221#1107#1010#2126Bed.: z < mm > maxCode

Page 19: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

19 Funktionales Programm

verschluesselnZahl

(2102, 3000) 2221

119

Spezifikation:

schluessel

zahl

Implementierung:def verschluesselnZahl(zahl, schluessel): return (zahl + schluessel[0]) % schluessel[1]

Verschlüsselung:

öffentlicher Schlüssel(d, m) = (2102, 3000)

z → (z + d) % m 0119#2005#1809#24

2221#1107#1010#2126Bed.: z < mm > maxCode

Page 20: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

20 Funktionales Programm

verschluesseln

(2102, 3000) [2221, 1107, 1010, 2126]

[119, 2005, 1809, 24]

Spezifikation:

schluessel

zahlenListe

Implementierung:def verschluesseln(zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahl(zahlenListe[0], schluessel)] + verschluesseln(zahlenListe[1:], schluessel)

Verschlüsselung:

öffentlicher Schlüssel(d, m) = (2102, 3000)

z → (z + d) % m 0119#2005#1809#24

2221#1107#1010#2126Bed.: z < mm > maxCode

Page 21: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

21 Datenstruktur "Tupel"

verschluesselnZahl

(2102, 3000) 2221

119

Spezifikation:

schluessel

zahl

Implementierung:def verschluesselnZahl(zahl, schluessel): return (zahl + schluessel[0]) % schluessel[1]

Tupel

Zugriff auf die KomponentenZugriff auf die Komponenten

Tupel sind unveränderbare Sequenzen. Man verwendet Tupel, wenn man ein Objekt repräsentieren möchte, das aus mehreren Komponenten besteht.

Page 22: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

22 Datenstruktur "Liste"

Liste

Listenoperationen

verschluesseln

(2102, 3000) [2221, 1107, 1010, 2126]

[119, 2005, 1809, 24]

schluessel

zahlenListe

Implementierung:def verschluesseln(zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahl(zahlenListe[0], schluessel)] + verschluesseln(zahlenListe[1:], schluessel)

Liste

Spezifikation:

Listen sind veränderbare Sequenzen. Sie können (in Python) Objekte beliebigen Typs enthalten. Mit Listen kann man komplexere Strukturen modellieren.

Page 23: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

23 Listenoperationen

leere Liste

Länge einer Liste

Zugriff auf Listenelemente

Zugriff auf eine Restliste

>>> zahlenListe = []>>> zahlenListe[]>>> len(zahlenListe)0>>> zahlenListe = [119, 2005, 1809, 24]>>> zahlenListe[119, 2005, 1809, 24]>>> zahlenListe[0]119>>> zahlenListe[1:][2005, 1809, 24]>>> [zahlenListe[0]] + zahlenListe[1:][119, 2005, 1809, 24]>>> ...

Konkatenation von Listen

Das Python-Protokoll zeigt die Listenoperationen, die im Folgenden benötigt werden. Weitere Listenoperationen findet man in der Dokumentation.

Page 24: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

24 Aufgabe

>>> zahlenListe = []>>> zahlenListe[]>>> len(zahlenListe)0>>> zahlenListe = [119, 2005, 1809, 24]>>> zahlenListe[119, 2005, 1809, 24]>>> zahlenListe[0]119>>> zahlenListe[1:][2005, 1809, 24]>>> [zahlenListe[0]] + zahlenListe[1:][119, 2005, 1809, 24]>>> ...

Testen Sie die im funktionalen Programm vorkommenden Listenoperationen. Variieren Sie dabei auch die vorkommenden Parameterwerte.

Page 25: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

25 Rekursive Problemreduktion

verschluesseln([119, 2005, 1809, 24], (2102, 3000))

→ [verschluesselnZahl(119, (2102, 3000))] +

verschluesseln([2005, 1809, 24], (2102, 3000))

Fall 2: Bearbeite eine nicht-leere Liste

[2221]

[2221, 1107, 1010, 2126]

[1107, 1010, 2126]

verschluesseln([], (2102, 3000))

→ []

Fall 1: Bearbeite eine leere Liste

[]

Rekursionsanfang: Löse das Problem direkt

Rekursionsschritt: Löse ein entsprechendes

Problem

Rekursive Problemreduktion: Reduziere des Problems auf ein entsprechendes, aber „verkleinertes“ Problem.

Page 26: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

26 Aufgabe

def verschluesseln(zahlenListe, schluessel): print zahlenListe, schluessel if len(zahlenListe) == 0: return [] else: return [verschluesselnZahl(zahlenListe[0], schluessel)] + verschluesseln(zahlenListe[1:], schluessel)

Fügen Sie Ausgabeanweisungen ein und verfolgen Sie so die Auswertung der einzelnen Funktionsaufrufe.

Page 27: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

27 Kontrollstruktur "Rekursion"

def verschluesseln(zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahl(zahlenListe[0], schluessel)] + verschluesseln(zahlenListe[1:], schluessel)

verschluesseln([119, 2005, 1809, 24], (2102, 3000))

→ [verschluesselnZahl(119, (2102, 3000))] + verschluesseln([2005, 1809, 24], (2102, 3000))

→ [2221] + verschluesseln([2005, 1809, 24], (2102, 3000))

→ [2221] + [verschluesselnZahl(2005, (2102, 3000))] + verschluesseln([1809, 24], (2102, 3000))

→ [2221] + [1107] + verschluesseln([1809, 24], (2102, 3000)) ...

Rekursion wird in der funktionalen Programmierung als Kontrollstruktur benutzt, um wiederkehrende Berechnungen durchzuführen.

Page 28: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

28 Kontrollstruktur "Rekursion"→ [2221] + [1107] + [verschluesselnZahl(1809, (2102, 3000))] + verschluesseln([24], (2102, 3000))

→ [2221] + [1107] + [1010] + verschluesseln([24], (2102, 3000))

→ [2221] + [1107] + [1010] + [verschluesselnZahl(24, (2102, 3000))] + verschluesseln([], (2102, 3000))

→ [2221] + [1107] + [1010] + [2126] + verschluesseln([], (2102, 3000))

→ [2221] + [1107] + [1010] + [2126] + []

→ [2221, 1107, 1010, 2126]

Page 29: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

29 Kontrollstrukturen

Funktionsdeklarationen werden in der funktionalen Programmierung mit Hilfe von - Funktionskomposition,- Fallunterscheidungen und- Rekursion aufgebaut. Diese Strukturen legen letztlich die Ablaufkontrolle fest.

def verschluesseln(zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahl(zahlenListe[0], schluessel)] + verschluesseln(zahlenListe[1:], schluessel)

Fallunterscheidung Rekursion Funktionskomposition

Page 30: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

30 Aufgabe

Zur Übung rekursiver Funktionsdeklarationen sollen folgende Funktionen implementiert werden. Gehen Sie analog zur Funktion "verschluesseln" vor.

addieren

7 [13, 20, 7, 12]

[6, 13, 0, 5]

konstante

zahlenListe

Spezifikation:

nullErsetzen

7 [6, 7, 13, 7, 7, 5, 3]

[6, 0, 13, 0, 0, 5, 3]

konstante

zahlenListe

Spezifikation:

Page 31: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

31 Aufgabe

In der Datei "ChiffriersystemModularesAddierenRekursiv.py" finden Sie eine Implementierung des Chiffriersystems basierend auf modularer Addition, die (außer zum Testen) keine Wertzuweisungen benutzt. Analysieren Sie die Funktionsdeklarationen auch im Hinblick auf die vorkommenden Kontrollstrukturen.

Verschlüsselung:

öffentlicher Schlüssel(d, m) = (2102, 3000)

z → (z + d) % m 0119#2005#1809#24

2221#1107#1010#2126

Entschlüsselung:

privater Schlüssel(e, m) = (898, 3000)

z → (z + e) % m 2221#1107#1010#2126

0119#2005#1809#24

Bed.: z < mm > maxCode

Bed.: (d + e) % m = 0

Page 32: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

32 Aufgabe

Ändern Sie die entsprechenden Funktionsdeklarationen so ab, dass man das multiplikative Chiffrierverfahren erhält.

Verschlüsselung:

öffentlicher Schlüssel(d, m) = (7, 30)

z → (z * d) % m 01#19#20#05#18#09#24

07#13#20#05#06#03#18

Entschlüsselung:

privater Schlüssel(e, m) = (13, 30)

z → (z * e) % m 07#13#20#05#06#03#18

01#19#20#05#18#09#24

Bed.: z < m

Bed.: (d * e) % m = 1

Page 33: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

33 Codeduplizierung

Die Implementierungen zur Verschlüsselung mit modularer Addition und modularer Multiplikation weisen auffallende Ähnlichkeiten auf.def verschluesselnZahlAdd(zahl, schluessel): return (zahl + schluessel[0]) % schluessel[1]

def verschluesselnAdd(zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahlAdd(zahlenListe[0], schluessel)] + verschluesselnAdd(zahlenListe[1:], schluessel)

def verschluesselnZahlMul(zahl, schluessel): return (zahl * schluessel[0]) % schluessel[1]

def verschluesselnMul(zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahlMul(zahlenListe[0], schluessel)] + verschluesselnMul(zahlenListe[1:], schluessel)

Page 34: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

34 Funktionen als Eingabeobjekte

Funktion

verschluesseln

(2102, 3000) [2221, 1107, 1010, 2126]

[119, 2005, 1809, 24]

schluessel

zahlenListe

Spezifikation:

verfahrenz → (z + d) % m

Liste Tupel

Codeduplizierung lässt sich vermeiden, wenn man Funktionen als Eingabeobjekte von Funktionen zulässt.

Page 35: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

35 Funktionen als Eingabeobjekte

def verschluesselnZahlAddieren(zahl, schluessel): return (zahl + schluessel[0]) % schluessel[1]

def verschluesselnZahlMultiplizieren(zahl, schluessel): return (zahl * schluessel[0]) % schluessel[1]

def verschluesselnZahl(verfahren, zahl, schluessel): return verfahren(zahl, schluessel)

def verschluesseln(verfahren, zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahl(verfahren, zahlenListe[0], schluessel)] + verschluesseln(verfahren, zahlenListe[1:], schluessel)

def verschluesselnModularesAddieren(zahlenListe, schluessel): return verschluesseln(verschluesselnZahlAddieren, zahlenListe, schluessel)

def verschluesselnModularesMultiplizieren(zahlenListe, schluessel): return verschluesseln(verschluesselnZahlMultip.., zahlenListe, schluessel)

Die Implementierung zeigt, dass man Funktionen hier wie andere Objekte auch als Parameter übergeben kann.

Page 36: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

36 Aufgabe

Testen Sie die Implementierung in der Datei "ChiffriersystemModularesRechnenRekursiv.py".

Erweitern Sie diese Implementierung um die Möglichkeit, Verschlüsselung auch mit modularem Potenzieren durchzuführen.

Page 37: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

37 Funktionale Programmierung

def verschluesseln(zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahl(zahlenListe[0], schluessel)] + verschluesseln(zahlenListe[1:], schluessel)

verschluesseln([119, 2005, 1809, 24], (2102, 3000))

Mit Funktionen kann man programmieren. Die Programme bestehen aus Funktionsdeklarationen. Ein Programmaufruf erfolgt mit einem funktionalen Berechnungsausdruck.

Funktionsdeklaration

Berechnungsausdruck

Page 38: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

38 Funktionale Programmierung

def verschluesselnZahl(zahl, schluessel): return (zahl + schluessel[0]) % schluessel[1]

def verschluesseln(zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahl(zahlenListe[0], schluessel)] + verschluesseln(zahlenListe[1:], schluessel)

Funktionsdeklarationen werden mit Hilfe von - Funktionskomposition,- Fallunterscheidungen und- Rekursion aufgebaut.

Fallunterscheidung

Rekursion

Funktionskomposition

Page 39: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

39 Funktionale Programmierung

def verschluesselnZahl(verfahren, zahl, schluessel): return verfahren(zahl, schluessel)

def verschluesseln(verfahren, zahlenListe, schluessel): if len(zahlenListe) == 0: return [] else: return [verschluesselnZahl(verfahren, zahlenListe[0], schluessel)] + verschluesseln(verfahren, zahlenListe[1:], schluessel)

Objekte können mit Hilfe von Tupelbildung und Listen zu neuen Einheiten zusammengefasst werden.

Funktionen können als Eingabeobjekte für weitere Funktionen benutzt werden.

Funktion

Liste

Tupel

Page 40: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

40 Miniprojekte

Funktionale Programmierung eignet sich sehr gut, um schnell ein System zu entwickeln und zu testen. Man konzentriert sich nur auf die "Logik" des Systems, nicht auf "schmückendes Beiwerk". Die Programme sollen dabei kurz und gut überschaubar sein.

Im Folgenden soll diese Vorgehensweise anhand von drei Miniprojekten aufgezeigt werden.

Page 41: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

41

Miniprojekt "Geometrische Abbildungen"

Ziel ist es, ein System zu entwickeln, mit dem man einfache geometrische Operationen durchführen kann.

Page 42: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

42 Miniprojekt "Automatensimulator"

Ziel ist es, ein System zu entwickeln, mit dem man das Verhalten eines beliebigen Automaten simulieren kann.

1

g u

00

1

0 0 0 1 1 0 1 1

Ok!

akzeptor

Page 43: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

43 Miniprojekt "Programminterpreter"

Ziel ist es, ein System zur Ausführung einfacher imperativer Programme zu entwickeln.

BEGINp := 1;WHILE u > 0 DO BEGIN IF u mod 2 = 1 THEN BEGIN u := u – 1; p := p * b; END; u := u div 2; b := b* b; ENDEND

Interpreter

{b: 2; u: 5}

{b: 256; u: 0; p: 32}

Page 44: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

44 Aufgabe

Wählen Sie eines der Miniprojekte aus und realisieren Sie das skizzierte System. Sie können versuchen, das System völlig selbständig zu entwickeln, oder die im Folgenden angebotenen Hilfen zu nutzen.

Page 45: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

45 Teil 3

Miniprojekt: Geometrische Abbildungen

Page 46: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

46 Geometrische Abbildungen

Ziel ist es, ein System zu entwickeln, mit dem man einfache geometrische Operationen durchführen kann.

Page 47: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

47 Schritt 1: Verschiebungen

Verschiebungen können mit Hilfe von Vektoren dargestellt werden. Die Abbildung von Punkten lässt sich dann durch Addition von Vektoren realisieren.

Vieleck:

A(0, 0), B(40, 0), C(40, 30), D(0, 30)

Verschiebung mit Vektor:

10v = 10

verschobenes Vieleck:

A'(10, 10), B'(50, 10), C'(50, 40), D'(10, 40)

Page 48: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

48 Listenrepräsentation

Wir repräsentieren Vektoren mit Hilfe von Listen. Ebenso stellen wir Punkte und Punktfolgen mit Hilfe von Listen dar.

Vieleck:

[[0, 0], [40, 0], [40, 30], [0, 30]]

Verschiebung mit Vektor [10, 10]:

[0, 0] + [10, 10] [10, 10][40, 0] + [10, 10] [50, 10][40, 30] + [10, 10] [50, 40][0, 30] + [10, 10] [10, 40]

verschobenes Vieleck:

[[10, 10], [50, 10], [50, 40], [10, 40]]

Page 49: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

49 Aufgabe

Entwickeln Sie ein funktionales Programm für die Addition von Vektoren. Um das Programm flexibel benutzen zu können, sollen Vektoren beliebig viele Komponenten haben können.

Spezifikation:add

[10, 0, 30] [70, 30, 70]

[60, 30, 40]

w

v

Page 50: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

50 Aufgabe

Realisieren Sie jetzt die Abbildung "Verschieben" mit Hilfe der bereits implementierten Vektoraddition.

verschiebenPunkt

[10, 10] [50, 30]

[40, 30]

vektor

punkt

Spezifikation:

verschieben

[10, 10] [[30, 20], [50, 40], [80, 10]]

[[20, 10], [40, 30], [70, 0]]

vektor

vieleck

Spezifikation:

Page 51: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

51 Lösungsvorschlag

add

[10, 0, 30] [70, 30, 70]

[60, 30, 40]

w

v

Spezifikation:

def add(v, w): if len(v) == 0: if len(w) == 0: return [] else: return w else: if len(w) == 0: return v else: return [v[0] + w[0]] + add(v[1:], w[1:])

Implementierung:

Page 52: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

52 Lösungsvorschlag

def verschiebenPunkt(punkt, vektor): return add(punkt, vektor)

def verschieben(vieleck, vektor): if len(vieleck) == 0: return [] else: return [verschiebenPunkt(vieleck[0], vektor)] + verschieben(vieleck[1:], vektor)

verschiebenPunkt

[10, 10] [50, 30]

[40, 30]

vektor

punkt

Spezifikation:

verschieben

[10, 10] [[30, 20], [50, 40], [80, 10]]

[[20, 10], [40, 30], [70, 0]]

vektor

vieleck

Spezifikation:

Page 53: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

53 Test mit Turtlegrafik

Testen Sie die einzelnen Funktionsdeklarationen mit Hilfe geeigneter Testfälle.

Zur visuellen Kontrolle können Sie die geometrischen Objekte auch mit Hilfe von Turtlegrafik darstellen. Kopieren Sie zu diesem Zweck die Daten "xturtle.py" (von G. Lingl aus dem Buch "Python für Kids") in die Standardbibliothek von Python. Benutzen Sie die Hilfsfunktion zum Zeichnen von Vielecken (siehe "GeometrischeOperationen1.py"). Beachten Sie, dass diese Hilfsfunktion Seiteneffekte in Form von Grafiken erzeugt und damit nicht mehr rein funktional ist.

Page 54: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

54 Test mit Turtlegrafik

def zeichneVieleck(punkte): # wird nur zum Zeichnen benutzt if len(punkte) > 0: penup() setpos(punkte[0]) pendown() streckenzug = punkte[1:] + [punkte[0]] for punkt in streckenzug: goto(punkt)

if __name__ == "__main__": # Test der einzelnen Funktionen import doctest doctest.testmod(verbose=True) # Visueller Test mit Turtlegrafik from xturtle import * reset() vieleck1 = [[0, 0], [40, 0], [40, 30], [0, 30]] vieleck2 = verschieben(vieleck1, [10, 10]) zeichneVieleck(vieleck1) zeichneVieleck(vieleck2)

Page 55: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

55 Schritt 2: Streckungen

Streckungen lassen sich durch Multiplikation eines Vektors mit einer Zahl realisieren.

Fall1: Streckzentrum im Ursprung Streckung mit dem Faktor k:multipliziere die Koordinaten der Punkte mit dem Streckfaktor k

Fall 2: Streckzentrum beliebigVerschiebe erst das Streckzentrum in den Ursprung, führe die Steckung aus und verschiebe wieder zurück an den Ausgangspunkt

Beispiel:

Vieleck: A(30, 0), B(70, 0), C(70, 30), D(30, 30)

Streckung mit dem Streckzentrum (0, 0) und dem Streckfaktor 2:

gestrecktes Vieleck: A'(60, 0), B'(140, 0), C'(140, 60), D'(60, 60)

Page 56: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

56 Listenrepräsentation

Wir benötigen hier die Multiplikation eines Vektors mit einer Zahl.

Vieleck:

[[20, 0], [60, 0], [60, 30], [20, 30]]

Streckung mit dem Streckzentrum [0, 0] und dem Streckfaktor 2:

2*[20, 0] [40, 0]...

gestrecktes Vieleck:

[[40, 0], [120, 0], [120, 60], [40, 60]]

Page 57: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

57 Aufgabe

Entwickeln Sie geeignete Funktionen zur Durchführung von Streckungen.

Page 58: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

58 Lösungsvorschlag

def mul(k, v): if len(v) == 0: return [] else: return [k * v[0]] + mul(k, v[1:])

def streckenPunktUrsprung(punkt, faktor): return mul(faktor, punkt)

def streckenUrsprung(vieleck, faktor): if len(vieleck) == 0: return [] else: return [streckenPunktUrsprung(vieleck[0], faktor)] + streckenUrsprung(vieleck[1:], faktor)

def strecken(vieleck, zentrum, faktor): return verschieben( streckenUrsprung( verschieben(vieleck, mul(-1, zentrum)), faktor), zentrum)

Page 59: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

59 Schritt 3: Drehungen

Drehungen lassen sich durch Multiplikation einer Matrix mit einem Vektor realisieren.

Fall1: Drehzentrum im Ursprung Drehung des Punktes P(x, y) um den Winkel w:

cos(w) -sin(w) x x'

* sin(w) cos(w) y y'

Es gilt:

x' = cos(w)*x + (- sin(w))*y

y' = sin(w)*x + cos(w)*y

Fall 2: Drehzentrum beliebigVerschiebe erst das Drehzentrum in den Ursprung, führe die Drehung aus und verschiebe wieder zurück an den Ausgangspunkt

Page 60: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

60 Listenrepräsentation

Wir repräsentieren Matrizen hier ebenfalls mit Hilfe von Listen.:

Vieleck:

[[20, 0], [60, 0], [60, 30], [20, 30]]

Matrix für eine Linksdrehung um das Drehzentrum [0, 0] und dem Drehwinkel 90°: [[0, -1], [1, 0]]

[[0, -1], [1, 0]] * [20, 0] [0, 20]...

gedrehtes Vieleck:

[[0, 20], [0, 60], [-30, 60], [-30, 20]]

Page 61: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

61 Aufgabe

Entwickeln Sie geeignete Funktionen zur Durchführung von Drehungen. Bei der Implementierung mit Python müssen Sie durch "import math" die benötigten mathematischen Operationen bereitstellen. Ein Aufruf der cos-Funktion lautet hier "math.cos(x)". Das Ergebnis wird im Bogenmaß geliefert. Mit "math.radians(w)" können Sie einen Winkel im Gradmaß ins Bogenmaß umrechen. Die umgekehrte Operation führt "math.degrees(x)" aus. Weitere Informationen erhalten Sie in der mitgelieferten Dokumentation.

Page 62: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

62 Lösungsvorschlag

def skalprod(v, w): if len(v) == 0: return 0 else: return (v[0] * w[0]) + skalprod(v[1:], w[1:])

def matrixmul(m, v): if len(m) == 0: return [] else: return [skalprod(m[0], v)] + matrixmul(m[1:], v)

Page 63: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

63 Lösungsvorschlag

def drehenPunktUrsprung(punkt, w): import math return matrixmul([ [math.cos(math.radians(w)), -math.sin(math.radians(w))], [math.sin(math.radians(w)), math.cos(math.radians(w))]], punkt)

def drehenUrsprung(vieleck, w): if len(vieleck) == 0: return [] else: return [drehenPunktUrsprung(vieleck[0], w)] + drehenUrsprung(vieleck[1:], w)

def drehen(vieleck, zentrum, winkel): return verschieben( drehenUrsprung( verschieben(vieleck, mul(-1, zentrum)), winkel), zentrum)

Page 64: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

64 Weitere Ideen

Erweitern Sie das System um die Möglichkeit, Spiegelungen durchzuführen.

Page 65: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

65 Teil 4

Miniprojekt: Automatensimulator

Page 66: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

66 Miniprojekt "Automatensimulator"

Ziel ist es, ein System zu entwickeln, mit dem man das Verhalten eines beliebigen Automaten simulieren kann.

1

g u

00

1

0 0 0 1 1 0 1 1

Ok!

akzeptor

Page 67: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

67 Schritt 1: Automatenbeschreibung

Mit Hilfe endlicher Automaten kann man formale Sprachen erkennen. Der dargestellte endliche Automat erkennt die Sprache der 0-1-Wörter mit gerader Parität (gerader Anzahl von 1en). Es handelt sich um einen sog. Akzeptor, der keine Ausgaben erzeugt.

Zustandsmenge: Z = {g, u}

Eingabemenge: E = {0, 1}

Anfangszustand: za = g

Endzustände: zE = {g}

Überführungsfunktion: : (g, 0) g : (g, 1) u : (u, 0) u: (u, 1) g

1

g u

00

1

Page 68: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

68 Aufgabe

Der Automat lässt sich wie folgt mit Funktionen modellieren. Implemen-tieren Sie diese Funktionen.

Zustandsmenge: Z = {g, u}

Eingabemenge: E = {0, 1}

Anfangszustand: za = g

Endzustände: zE = {g}

Überführungsfunktion: : (g, 0) g : (g, 1) u : (u, 0) u: (u, 1) g

1

g u

00

1

Spezifikation:deltaP

'0' 'g'

'g'

e

z

Spezifikation:endzustandP

True'g' z

Spezifikation:anfangszustandP

'g'

Page 69: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

69 Aufgabe

Modellieren und implementieren Sie noch einen weiteren Automaten (ohne Ausgabe).

Page 70: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

70 Aufgabe

Der unten abgebildete Automat zur Steuerung einer Ampel ist ein Transduktor. In jedem Zustand wird bei jeder Eingabe eine Ausgabe erzeugt. Z. B. wird im Zustand "rot" bei der Eingabe "t" (Tag) die Ausgabe "OOo" (rot an, gelb an, grün aus) erzeugt. Beschreiben Sie diesen Transduktor mit Hilfe von Funktionen.

Page 71: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

71 Lösungsvorschlag

Zustandsmenge: Z = {g, u}

Eingabemenge: E = {0, 1}

Anfangszustand: za = g

Endzustände: zE = {g}

Überführungsfunk.: : (g, 0) g

: (g, 1) u : (u, 0) u: (u, 1) g

1

g u

00

1

def anfangszustandP(): return 'g'

def endzustandP(z): if (z == 'g'): return True elif (z == 'u'): return False

def deltaP(z, e): if (z == 'g') and (e == '0'): return 'g' elif (z == 'u') and (e == '0'): return 'u' elif (z == 'g') and (e == '1'): return 'u' elif (z == 'u') and (e == '1'): return 'g'

Page 72: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

72 Lösungsvorschlag

def anfangszustandA(): return 'ge';;

def deltaA(z, e): if (z == 'ro') and (e == 't'): return 'rg' elif (z == 'rg') and (e == 't'): return 'gr' elif (z == 'gr') and (e == 't'): return 'ge' elif (z == 'ge') and (e == 't'): return 'ro' ...

def lambdaA(z, e): if (z == 'ro') and (e == 't'): return 'OOo' elif (z == 'rg') and (e == 't'): return 'ooO' elif (z == 'gr') and (e == 't'): return 'oOo' ...

Page 73: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

73

Schritt 2: Verarbeitung v. Eingabefolgen

Es soll ein Akzeptor-System entwickelt werden, mit dem eine Folge von Eingaben verarbeiten werden kann und rückgemeldet wird, ob diese Folge in einen Endzustand überführt.

1

g u

00

1

0 0 0 1 1 0 1 1 Ok!

Page 74: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

74 Aufgabe

Erweitern Sie das funktionale Programm um die spezifizierten Funktionen. Tipp: siehe nächste Folie

Spezifikation:simulatorP

['0', '1', '0']

'u''g'

eListe

z

Spezifikation:akzeptorP

False

eListe['0', '1', '0']

def anfangszustandP(): return 'g'

def endzustandP(z): if (z == 'g'): return True elif (z == 'u'): return False

def deltaP(z, e): if (z == 'g') and (e == '0'): return 'g' elif (z == 'u') and (e == '0'): return 'u' elif (z == 'g') and (e == '1'): return 'u' elif (z == 'u') and (e == '1'): return 'g'

1

g u

00

1

Page 75: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

75 Aufgabe

Tipp:Verallgemeinern Sie die unten an konkreten Beispielen gezeigten Problemreduktionen. 1

g u

00

1

Fall 1: Verarbeite eine leere Eingabenliste

simulartorP('g', []) 'g'

simulatorP('g', ['1', '0', '0']) simulatorP('u', ['0', '0'])]

u 'u'

Fall 2: Verarbeite eine nicht-leere Eingabenliste

Page 76: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

76 Aufgabe

Entwickeln Sie eine Funktion zur Realisierung eines Ampelsimulators.

Spezifikation:simulatorA

['t', 't', 't', 't']

[OOo, ooO, oOo, Ooo]'ro'

eListe

z

Page 77: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

77 Lösungsvorschlag

def simulatorP(z, eListe): if len(eListe) == 0: return z else: return simulatorP(deltaP(z, eListe[0]), eListe[1:])

Fall 1: Verarbeite eine leere Eingabenliste

simulartorP('g', []) 'g'

simulatorP('g', ['1', '0', '0']) simulatorP('u', ['0', '0'])]

u 'u'

Fall 2: Verarbeite eine nicht-leere Eingabenliste

def akzeptorP(eListe): return enzustand(simulatorP(anfangszustand(), eListe))

Page 78: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

78 Weitere Ideen

Entwickeln Sie ein System, bei dem die Arbeitsweise eines Transduktors (Automat mit Ausgabe) simuliert wird.

Page 79: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

79 Schritt 3: Automat als Eingabe

Es soll ein universelles Akzeptor-System entwickelt werden, mit dem eine Folge von Eingaben mit einem beliebig vorgegebenen Automaten verarbeiten werden kann.

0 0 0 1 1 0 1 1

Ok!

def anfangszustandP(): ...def endzustandP(z): ...def deltaP(z, e): ...

Page 80: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

80 Aufgabe

Eine Automatenbeschreibung ist ein Tripel (az, ez, de) mit:

- az ist eine Funktion zur Beschreibung des Anfangszustands.

- ez ist eine Funktion zur Beschreibung der Endzustände.

- de ist eine Überführungsfunktion, die jedem Zustand und jeder Eingabe aus einen neuen Zustand zuordnet.

Funktionen

simulator

'u'eListe

z

Spezifikation:

aut(anfangszustandP, enzustandP, deltaP)

['0', '1', '0']

'g'

Verallgemeinern Sie das bisher entwickelte Simulator-System. Benutzen Sie die folgende Vereinbarung:

Page 81: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

81 Lösungsvorschlag

def simulator(aut, z, eListe): if len(eListe) == 0: return z else: return simulator(aut, aut[2](z, eListe[0]), eListe[1:])

def akzeptor(aut, eListe): return aut[1](simulator(aut, aut[0](), eListe))

Page 82: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

82 Weitere Ideen

Entwickeln Sie ein System, bei dem die Arbeitsweise eines beliebigen Transduktors simuliert wird.

Page 83: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

83 Teil 5

Miniprojekt: Programminterpreter

Page 84: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

84 Miniprojekt "Programminterpreter"

Ziel ist es, ein System zur Ausführung einfacher imperativer Programme zu entwickeln.

BEGINp := 1;WHILE u > 0 DO BEGIN IF u mod 2 = 1 THEN BEGIN u := u – 1; p := p * b; END; u := u div 2; b := b* b; ENDEND

Interpreter

{b: 2; u: 5}

{b: 256; u: 0; p: 32}

Page 85: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

85 Problemvereinfachung

Wir betrachten zunächst nur Programme, die aus "primitiven Zuweisungen" vom Typ <Var> := <Var> bestehen.

BEGINz := x;x := y;y := zEND

Interpreter

{x: 2; y: 5}

{x: 5; y: 2; z: 5}

Ausgangs-zustand

End-zustand

Zuweisungs-programm

Page 86: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

86 Funktionale Modellierung

Spezifikation:PrimZuwSeqAusfuehr

en

[('x', 2), ('y', 5)][('x', 5), ('y', 2), ('z', 5)]

[(':=', 'z', 'x'), (':=', 'x', 'y'), (':=', 'y', 'z')]

zustand

zuweisungen

BEGINz := x;x := y;y := zEND

Interpreter

{x: 2; y: 5}

{x: 5; y: 2; z: 5}

Ausgangs-zustand

End-zustand

Zuweisungs-programm

Page 87: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

87 Schritt 1: Variablenzustände

Variablenzustände beschreiben die jeweils aktuellen Variablenbelegungen. Zur Verarbeitung einer primitiven Zuweisung wie z := x muss der Wert einer Variablen (hier x) bzgl. des aktuellen Variablenzustands ermittelt werden und der Wert einer Variablen (hier y) im Variablenzustand verändert (oder neu angelegt) werden.

{x: 2; y: 5}

z := x;

{x: 2; y: 5; z: 2}

x := y;

{x: 5; y: 5; z: 2}

y := z

{x: 5; y: 2; z: 2}

Page 88: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

88 Aufgabe

Modellieren Sie geeignete Funktionen, mit denen der Wert einer Variablen bzgl. eines Variablenzustands ermittelt werden kann und der Wert einer Variablen im Variablenzustand verändert (oder neu angelegt) werden kann.

Entwickeln Sie anschließend mit Hilfe rekursiver Problemreduktionsschemata geeignete Funktionsdeklarationen.

Page 89: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

89 Lösungsvorschlag

Spezifikation:VariablenWert

[('x', 2), ('y', 5)]5

'y'

zustand

Spezifikation:NeuerZustand

2 wert

bezeichner

[('x', 2), ('y', 5)] zustand

'z' [('x', 2), ('y', 5), ('z', 2)]

NeuerZustand

5 wert

bezeichner

[('x', 2), ('y', 5), ('z', 2)] zustand

'x' [('x', 5), ('y', 5), ('z', 2)]

bezeichner

Page 90: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

90 Lösungsvorschlag

def VariablenWert(bezeichner, zustand): if len(zustand) == 0: return '?' else: if bezeichner == zustand[0][0]: return zustand[0][1] else: return VariablenWert(bezeichner, zustand[1:])

def NeuerZustand(bezeichner, wert, zustand): if len(zustand) == 0: return [(bezeichner, wert)] else: if bezeichner == zustand[0][0]: return [(bezeichner, wert)] + zustand[1:] else: return [zustand[0]] + NeuerZustand(bezeichner, wert, zustand[1:])

Page 91: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

91 Schritt 2: Zuweisungsinterpreter

Mit Hilfe geeigneter Funktionen sollen jetzt einzelne primitive Zuweisungen bzw. Sequenzen primitiver Zuweisungen ausgeführt werden.

{x: 2; y: 5}

z := x;

{x: 2; y: 5; z: 2}

x := y;

{x: 5; y: 5; z: 2}

y := z

{x: 5; y: 2; z: 2}

Page 92: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

92 Aufgabe

Modellieren und implementieren Sie die hierzu erforderlichen Funktionen.

Page 93: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

93 Lösungsvorschlag

Spezifikation:PrimZuwAusfuehren

[('x', 2), ('y', 5)]

(':=', 'z', 'y')

zustand

Spezifikation:

zuweisung [('x', 2), ('y', 5), ('z', 2)]

PrimZuwSeqAusfuehren

[('x', 2), ('y', 5)][('x', 5), ('y', 2), ('z', 5)]

[(':=', 'z', 'x'), (':=', 'x', 'y'), (':=', 'y', 'z')]

zustand

zuweisungen

Page 94: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

94 Lösungsvorschlag

def PrimZuwAusfuehren(zuweisung, zustand): return NeuerZustand(zuweisung[1], VariablenWert(zuweisung[2], zustand), zustand)

def PrimZuwSeqAusfuehren(zuweisungen, zustand): if len(zuweisungen) == 0: return zustand else: return PrimZuwSeqAusfuehren(zuweisungen[1:], PrimZuwAusfuehren(zuweisungen[0], zustand))

Page 95: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

95 Schritt 3: Terminterpreter

Auf der rechten Seite einer Zuweisung sollen jetzt auch beliebige Rechenterme erlaubt sein. Wir beschränken uns auf das Rechnen mit ganzen Zahlen. Als Rechenoperationen sollen daher +, -, *, / (Division ohne Rest), % (Rest bei der Division) betrachtet werden.

{x: 2; y: 5}

x := x-y;

{x: -3; y: 5}

y := x+y;

{x: -3; y: 2}

x := y-x

{x: 5; y: 2}

Page 96: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

96 Aufgabe

Ergänzen Sie die bereits begonnene Funktionsdeklaration und verallgemeinern Sie den Zuweisungsinterpreter. Beachten Sie die hier gewählte Darstellung von Termen, z. B.:

z+(x-y) wird dargestellt durch ('+', 'z', ('-', 'x', 'y'))x+1 wird dargestellt durch ('+', 'x', 1)

def TermWert(term, zustand): if isinstance(term, int): return term else: if not isinstance(term, tuple): return VariablenWert(term, zustand) else: if term[0] == '+': return TermWert(term[1], zustand) + TermWert(term[2], zustand) else: ...

Page 97: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

97 Schritt 4: Bedingungsinterpreter

Als nächstes sollen Anweisungen mit Bedingungen (wie z. B. if (x > 0) then ...) betrachtet werden. Hierzu muss der Interpreter Bedingungen auswerten können. Der Einfachheit halber betrachten wir nur Bedingungen vom Typ <Term> <Vergleich> <Term>. Logische Verknüpfungen von Bedingungen sollen also keine Rolle spielen.

Spezifikation:BooleWert

[('x', 2), ('y', 5)]

('>', 'y', ('+', 'x', 'x'))

zustand

termTrue

Page 98: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

98 Aufgabe

Entwickeln Sie analog zur Auswertung von Rechentermen eine Funktion zur Auswertung von Bedingungen.

Page 99: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

99 Schritt 5: Kontrollinterpreter

Ziel ist es, Fallunterscheidungs- und Wiederholungsanweisungen auszuführen, wie sie etwa im unten dargestellten Programm vorkommen.

BEGINp := 1;WHILE u > 0 DO BEGIN IF u mod 2 = 1 THEN BEGIN u := u – 1; p := p * b; END; u := u div 2; b := b* b; ENDEND

Page 100: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

100 Aufgabe

Überlegen Sie sich eine Darstellung von Kontrollanweisungen (wie im Programm) mit den von Python zur Verfügung gestellten Datenstrukturen. Entwickeln Sie geeignete Funktionen zur Ausführung dieser Anweisungen.

BEGINp := 1;WHILE u > 0 DO BEGIN IF u mod 2 = 1 THEN BEGIN u := u – 1; p := p * b; END; u := u div 2; b := b* b; ENDEND

Page 101: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

101 Lösungsvorschlag

Fallunterscheidung: ('if', (..Bedingung..), [..Then-Anweisungen..], [..Else-Anweisungen..])

Wiederholung:('while', (..Bedingung..), [..Anweisungen..])

BEGINp := 1;WHILE u > 0 DO BEGIN IF u mod 2 = 1 THEN BEGIN u := u – 1; p := p * b; END; u := u div 2; b := b* b; ENDEND

[(':=', 'p', 1), ('while', ('>', 'u', 0), [('if', ('==', ('%', 'u', 2), 1), [(':=', 'u', ('-', 'u', 1)), (':=', 'p', ('*', 'p', 'b'))],[]), (':=', 'u', ('/', 'u', 2)), (':=', 'b', ('*', 'b', 'b'))])]

Page 102: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

102 Lösungsvorschlag

def AnwAusfuehren(anweisung, zustand): if anweisung[0] == ':=': return NeuerZustand(anweisung[1], TermWert(anweisung[2], zustand), zustand) else: if anweisung[0] == 'if': if BooleWert(anweisung[1], zustand): return AnwSeqAusfuehren(anweisung[2], zustand) else: return AnwSeqAusfuehren(anweisung[3], zustand) else: if anweisung[0] == 'while': if BooleWert(anweisung[1], zustand): return AnwAusfuehren(anweisung, AnwSeqAusfuehren(anweisung[2], zustand)) else: return zustand

Page 103: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

103 Lösungsvorschlag

def AnwSeqAusfuehren(anweisungen, zustand): if len(anweisungen) == 0: return zustand else: return AnwSeqAusfuehren(anweisungen[1:], AnwAusfuehren(anweisungen[0], zustand))

Page 104: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

104 Lösungsvorschlag

def ProgrammAusfuehren(programm, zustand): return AnwSeqAusfuehren(programm, zustand)

Beachten Sie, dass ein Programm hier immer eine Anweisungssequenz ist, auch wenn es nur aus einer Anweisung besteht.

Page 105: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

105 Teil 6

Deklarative Programmierung

Page 106: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

106 Ein Problem - zwei Lösungen

Problem:Wie fügt man die Elemente einer Listen (die alle Zeichenketten sein sollen) zu einer einzigen Zeichenkette zusammen?

Lösung:

Wenn die Liste leer ist, dann ist die leere Liste bereits das Ergebnis. Wenn die Liste nicht leer ist, dann erhält man das Ergebnis wie folgt: Man fügt das erste Element vorne an die Zeichenkette, die man erhält, wenn man alle Elemente der Restliste zusammenfügt.

def zusammenfuegen(liste): if len(liste) == 0: return '' else: return liste[0] + zusammenfuegen(liste[1:])

Lösung:

Stell eine Hilfsliste "ergebnis" wie folgt zusammen:Starte mit der einer leeren Liste.Füge Schritt für Schritt alle Elemente der Liste jeweils am Ende der Hilfsliste ein. Die am Schluss erhaltene Hilfsliste ist die gesuchte Liste.

def zusammenfuegen(liste): ergebnis = '' for wort in liste: ergebnis = ergebnis + wort return ergebnis

Deklarativer Ansatz:Man beschreibt, welche Eigenschaften das Ergebnis haben soll, das man beim Zusammenfügen erhält.

Imperativer Ansatz:Man beschreibt Schritt für Schritt den Vorgang, wie man alle Elemente der Liste zusammenfügt.

Page 107: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

107 Imperative Programmierung

Ansatz: Beschreiben, wie die Ergebnisse berechnet werden sollenZentrale Bausteine imperativer Programme sind Wertzuweisungen, die i.a. den momentanen Variablenzustand (Speicherzustand) verändern. Imperative Programmierung ist wegen der Möglichkeit, Seiteneffekte zu produzieren, recht fehleranfällig.

Ansatz: Beschreiben, wie die Ergebnisse berechnet werden sollenZentrale Bausteine imperativer Programme sind Wertzuweisungen, die i.a. den momentanen Variablenzustand (Speicherzustand) verändern. Imperative Programmierung ist wegen der Möglichkeit, Seiteneffekte zu produzieren, recht fehleranfällig.

Register-maschine

def zusammenfuegen(liste): ergebnis = '' for wort in liste: ergebnis = ergebnis + wort return ergebnis

{liste: ['HA', 'LL', 'O']}

{ergebnis: 'HALLO']}E.-Zustand

A.-Zustand

Anweisungen

Imperative Programmierung besteht darin, eine (mehr oder weniger abstrakte) Maschine mit Hilfe von Anweisungen zu steuern.

Page 108: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

108 Deklarative Programmierung

Ansatz: Beschreiben, was in der Modellwelt gelten sollDie funktionale Programmierung arbeitet ohne Speichervariablen. Variablen kommen hier nur als Funktionsvariablen zur Übergabe von Funktionsargumenten vor. Seiteneffekte sind demnach in der funktionalen Programmierung nicht möglich. Das Verhalten einer Funktion wird vollständig durch die Funktionsdeklarationen festgelegt.

Ansatz: Beschreiben, was in der Modellwelt gelten sollDie funktionale Programmierung arbeitet ohne Speichervariablen. Variablen kommen hier nur als Funktionsvariablen zur Übergabe von Funktionsargumenten vor. Seiteneffekte sind demnach in der funktionalen Programmierung nicht möglich. Das Verhalten einer Funktion wird vollständig durch die Funktionsdeklarationen festgelegt.

Reduktions-maschine

def zusammenfuegen(liste): if len(liste) == 0: return '' else: return liste[0] + zusammenfuegen(liste[1:])

zusammenfuegen(['HA', 'LL', 'O'])

'HALLO'Ergebnis

Term

Deklarationen

Deklarative Programmierung besteht darin, den Problemkontext (Miniwelt) mit gegebenen Mitteln (hier: Funktionen) zu beschreiben.

Page 109: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

109 Fazit

Funktionale Programmierung erfolgt auf einem höheren Abstraktionsniveau:- keine Anweisungen an eine Maschine, - sondern Beschreibung funktionaler Zusammenhänge.

Konsequenzen:- Funktionale Programme sind kurz.- Funktionale Programme sind leicht zu verstehen.- Funktionale Programmierung ist wenig fehleranfällig.- Funktionale Programmierung eignet sich zum „Prototyping“.

Funktionale Programmierung erfolgt auf einem höheren Abstraktionsniveau:- keine Anweisungen an eine Maschine, - sondern Beschreibung funktionaler Zusammenhänge.

Konsequenzen:- Funktionale Programme sind kurz.- Funktionale Programme sind leicht zu verstehen.- Funktionale Programmierung ist wenig fehleranfällig.- Funktionale Programmierung eignet sich zum „Prototyping“.

Page 110: Funktionale Programmierung Klaus Becker 2007. 2 Programmieren mit Funktionen Zielsetzung: Einblick in die funktionale Programmierung gewinnen Grundideen.

110 Literaturhinweise

[Becker 99] K. Becker: Funktionale Programmierung. Materialien zum Lehrplan Informatik. LMZ 1999. (http://informatikag.bildung-rp.de/html/funktprog.html)

[Becker 00] K. Becker: Problemlösen mit dem Computeralgebrasystem Derive - informatisch betrachtet. (http://informatikag.bildung-rp.de/html/derive.html)

[Becker 04] K. Becker: Funktionale Programmierung mit Caml. (http://informatik.bildung-rp.de/fileadmin/user_upload/informatik.bildung-rp.de/Weiterbildung/pps/WB-FunktionaleProgrammierungCaml.pps)

[Fischbacher 97] T. Fischbacher: Funktionale Programmierung. In: LOG IN 17 (1997) Heft 3 / 4, S. 24-26.

[ISB 97] Staatliches Institut für Schulpädagogik und Bildungsforschung München (Hrsg.): Funktionales Programmieren in Gofer. Baustein zur Didaktik der Informatik. München, 1997.

[Puhlmann 98] H. Puhlmann: Funktionales Programmieren - Eine organische Verbindung von Informatikunterricht und Mathematik. In: LOG IN 18 (1998) Heft 2, S. 46-50.

[Schwill 93] A. Schwill: Funktionale Programmierung mit Caml. In: LOG IN 13 (1993) Heft 4, S. 20-30.

[Wagenknecht 94] Christian Wagenknecht: Rekursion. Ein didaktischer Zugang mit Funktionen. Bonn: Dümmlers Verlag 1994.

[Wolff von Gudenberg 96] J. Wolff. von Gudenberg: Algorithmen, Datenstrukturen, Funktionale Programmierung. Eine praktische Einführung mit Caml Light. Bonn: Addison-Wesley 1996.