Lothar Piepmeyer
Grundkurs funktionale Programmierung mit Scala
Inhaltsverzeichnis
8
Vorwort
16
I Abenteuer Lambda
18
1 Mehr denken, weniger tippen
20
1.1 Sag, was du willst!
20
1.2 Der alte Weg
21
1.3 Abstraktion der Hardware
22
1.4 Was ist funktionale Programmierung?
23
1.5 Funktionen – Unsere Bausteine
23
1.5.1 Was ist eine Funktion?
23
1.5.2 Was steckt in einer Funktion?
24
1.5.3 Eigenschaften von Funktionen
25
1.6 Die referentielle Transparenz
28
1.7 Das wirkliche Leben
29
2 Ein Hauch von Babylon
32
2.1 Lisp – Die Mutter aller funktionalen Sprachen
32
2.1.1 Listen – Der Stoff, aus dem Lisp gemacht ist
33
2.1.2 Operatoren in Lisp
34
2.1.3 Lambda-Ausdrücke
35
2.1.4 Mythos Lisp
37
2.2 ML – Der Pionier
38
2.2.1 Typableitung – Der Compiler erkennt den Typ
39
2.2.2 Muster und Ausdrücke
39
2.2.3 Generische Funktionen und Datentypen
41
2.3 Haskell – Funktionale Programmierung in Reinform
42
2.3.1 Haskell – Ein fauler Hund
43
2.4 Wann ist eine Sprache funktional?
45
2.5 Und die Performance?
45
2.6 Welche Sprache darf's denn sein?
46
2.6.1 Java
46
2.6.2 Scala
47
2.7 Aufgaben
48
II Die funktionale Seite von Java
50
3 Rekursion
52
3.1 Eine Schleife – was ist das eigentlich?
52
3.2 Die Rekursion – das unbekannte Wesen
53
3.3 Ist Rekursion praxistauglich?
54
3.4 Wie werden rekursive Funktionen verarbeitet?
55
3.5 Endrekursion, die schnelle Rekursion
57
3.6 Eine einfache Formel und ihre schwerwiegenden Folgen
60
3.7 Aufgaben
63
4 Alles bleibt, wie es ist
66
4.1 Konsistenz
66
4.2 Nichts ist beständiger als der Wandel
67
4.3 Versteckte Daten sind gute Daten
68
4.4 Invarianten – darauf ist Verlass
69
4.5 Ein Beispiel
71
4.6 Die Methode equals
72
4.7 Sichere Ergebnisse mit defensiven Kopien
72
4.8 Konkurrierende Zugriffe
74
4.9 Geänderte Hash-Codes
75
4.10 Unveränderbare Klassen
76
4.11 Performance
77
4.12 Unveränderbare Klassen in der Java-API
78
4.13 Aufgaben
79
5 Funktionen höherer Ordnung
80
5.1 Arrays sortieren leicht gemacht
80
5.2 Eine flexiblere Lösung
82
5.3 Funktionen als Ergebnisse von Funktionen
85
5.4 Aufgaben
88
6 Unveränderbare Listen
90
6.1 Arrays raus!
90
6.2 Verkettete Listen – Vom Nobody zum Star
91
6.3 Nützliche Methoden für die Arbeit mit Listen
93
6.4 Das schwer erreichbare Listenende
94
6.5 Die Faltung – eine universelle Funktion
95
6.6 Eine Leihgabe aus der imperativen Programmierung
98
6.7 Aufgaben
100
7 Anfragen an Listen
102
7.1 Auswahlen aus Listen
103
7.2 Listenelemente abbilden
104
7.3 Quicksort
105
7.4 Primzahlen
107
7.5 Verknüpfungen von Listen
108
7.6 Aufgaben
110
III Scala
112
8 Die Scala-Entwicklungsumgebung
114
8.1 Ohne Java geht nichts
114
8.2 Installation und erste Schritte
115
8.3 Scala-Skripts
115
8.4 Eigene Typen mit Scala-Klassen
116
8.5 Noch ein Compiler
117
8.6 Der Scala-Bazar
118
8.7 Aufgaben
119
9 Ausdrücke in Scala
122
9.1 Erste Eindrücke mit einfachen Ausdrücken
122
9.2 Konstante
123
9.3 Variable
125
9.4 Alle kennen Predef
125
9.5 Kontrollstrukturen
126
9.6 Importe
127
9.7 Aufgaben
127
10 Scala-Typsystem
130
10.1 In Scala gibt es keine primitiven Typen
130
10.2 Alles ist ein Objekt
131
10.3 Objekte vergleichen
132
10.4 Werte- und Referenztypen
133
10.5 Literale und Typumwandlungen
133
10.6 Der Typ Unit
134
10.7 Der Typ Null
134
10.8 Der Typ Nothing
135
10.9 Aufgaben
136
11 Methoden in Scala
138
11.1 Jede Methode hat einen Typ
138
11.2 Generische Methoden
139
11.3 Konstante als Grenzfall von Methoden
139
11.4 Was steht in einer Methode?
140
11.5 Methoden ohne Rückgabewert
142
11.6 Methoden in Methoden
142
11.7 Methoden für beliebig viele Argumente
143
11.8 Endrekursion
144
11.9 Aufgaben
146
12 Funktionen in Scala
148
12.1 Die Definition einer Funktion
148
12.2 Funktionen sind auch Objekte
150
12.3 Die partielle Anwendung einer Funktion
151
12.4 Eine scharfe Sache: Das Curry-Prinzip
153
12.5 Funktionen höherer Ordnung
155
12.6 Aufgaben
157
13 Tupel
160
13.1 Eigenschaften von Tupeln
161
13.2 Die Tupel-Klassen
162
13.3 Mustererkennung für Tupel
163
13.4 Aufgaben
164
14 Klassen und Vererbung in Scala
166
14.1 Klassendefinitionen in Scala
166
14.1.1 Ein alter Bekannter zum Einstieg
166
14.1.2 Konstruktoren
167
14.1.3 Attribute und parameterfreie Methoden
169
14.1.4 Mehrere Fliegen mit einer Klappe schlagen
170
14.1.5 Was bedeutet „rechtsassoziativ“?
171
14.2 Vererbung
171
14.2.1 Methoden überschreiben
171
14.2.2 Konstruktorverkettung
173
14.2.3 Polymorphie
174
14.2.4 Abstrakte Klassen
175
14.3 Aufgaben
176
15 Singletons: Objekte können einsam sein
178
15.1 Es kann nur einen geben
179
15.2 Statische Mitglieder waren gestern
180
15.3 Begleiter
180
15.4 Singletons zur Objektverwaltung
182
15.5 Singletons importieren
182
15.6 Aufgaben
183
16 Mustererkennung
184
16.1 Muster in Java
185
16.2 Einfache Muster in Scala
186
16.3 Muster für Tupel
187
16.4 Welche Muster gibt es?
188
16.5 Muster für Typen
189
16.6 Muster in Funktionen
191
16.7 Partielle Funktionen
191
16.8 Exceptions und Mustererkennung
192
16.9 Aufgaben
193
17 Extraktoren und Case-Typen
194
17.1 Besser als null: Der Typ Option
195
17.2 Extraktormuster
195
17.3 Optionale Attribute
196
17.4 Extraktoren sind universelle Inspektoren
197
17.5 Lesbarer Code mit apply
199
17.6 Variable Extraktoren
200
17.7 Alles frei Haus mit Case-Typen
200
17.8 Aufgaben
204
18 Listen
206
18.1 Die leere Liste
206
18.2 Listen erzeugen
207
18.3 Einfache Methoden für Listen
207
18.4 Listenmuster
208
18.5 Weitere einfache Methoden
209
18.6 Mengenoperationen
211
18.7 Das Begleitobjekt
212
18.8 Methoden höherer Ordnung für Listen
213
18.8.1 Beispiel: Quicksort
214
18.8.2 Die Faltung
215
18.9 Das Springerproblem
217
18.10 Aufgaben
219
19 Scala kann auch faul sein
220
19.1 Die Initialisierung kann warten
220
19.2 Faule Parameter mit Call-By-Name
222
19.3 Streams: Daten bei Bedarf
223
19.4 Unendliche Streams
225
19.5 Aufgaben
226
20 Es müssen nicht immer Listen sein
228
20.1 Mengen
228
20.2 Der Typ Set
230
20.3 Der Typ Map
231
20.4 Collections in anderen Geschmacksrichtungen
235
20.5 Aufgaben
236
21 Fast wie zu Hause: for-Ausdrücke
238
21.1 Eine nicht ganz so funktionale Methode höherer Ordnung
238
21.2 Komplexere for-Ausdrücke
239
21.3 for-Ausdrücke mit filter und map
239
21.4 Mehr Übersicht mit flatMap
240
21.5 for-Ausdrücke sind keine Schleifen
241
21.6 for-Ausdrücke für eigene Typen
242
21.7 Aufgaben
243
IV Scala kann mehr
244
22 Veränderbare Daten
246
22.1 Variable
246
22.2 Veränderbare Attribute
247
22.3 Die Rückkehr der Arrays
249
22.4 Aufgaben
250
23 Traits
252
23.1 Traits und Java-Interfaces
253
23.2 Konkrete Methoden
253
23.3 Mehrfachvererbung
255
23.4 Aufgaben
256
24 Varianz
258
24.1 Kovarianz von Java-Arrays
258
24.2 Kovarianz von generischen Java-Typen
259
24.3 Mehr Kovarianz in Java
260
24.4 Kontravarianz in Java
261
24.5 Varianz in Scala
261
25 Pakete und Sichtbarkeit
266
25.1 Pakete in Scala
266
25.2 Sichtbarkeit in Scala
267
25.3 Privater als privat
269
26 Typumwandlung
272
26.1 Implizite Methoden für implizite Casts
272
26.2 Wozu noch explizite Casts?
274
26.3 Angereicherte Typen
274
26.4 Pimp Your Library!
275
26.5 Sprachfeatures mit impliziten Casts umsetzen
276
26.6 Aufgaben
276
27 Parallele Programmierung mit Aktoren
278
27.1 Viele Köche verderben den Brei
279
27.2 Parallele Programmierung mal anders
279
27.3 Erste Versuche mit Aktoren
281
27.4 Der Typ Actor
282
27.5 Die Actor-Fabrik
283
27.6 Einfache Standardprobleme und ihre Lösung
284
27.7 Aktoren können antworten
285
27.8 Producer-Consumer-Probleme
286
27.9 Blockierende Stacks
288
27.10 Deadlocks – Nichts geht mehr
289
27.11 Aufgaben
293
Literaturverzeichnis
293
Stichwortverzeichnis
296
© 2009-2024 ciando GmbH