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 |