Unterdokumentierte Design Patterns

written by Martin Häcker on

Eine Frage die mich schon länger beschäftigt, ist das Finden von Design Patterns in Funktionalen Sprachen. Lange Zeit schien es mir so, als gäbe es da gar nichts, auch viele Programmierer, die in diesen Sprachen arbeiten, konnten mit dem Begriff nichts anfangen. Dabei gibt es meiner Meinung nach eine Menge, das man von funktionalen Sprachen lernen kann - und einiges, das schon gelernt wurde.

Einige Design Patterns, die ich seitdem gefunden habe, sind:

  • [wiki:BlogEntries/2006-02-23 Funktionen] als voll berechtigte Datentypen, d.h. man kann sie als Argument oder Rückgabewert in der Programmiersprache verwenden
  • Die Verwendung von Lambda-Ausdrücken (anonymen Funktionen)
    • Für Iteration, als Callback, für Fehlerbehandlung, Kontrollfluss...
  • Higher Order Funktionen - Funktionen als Argument und Rückgabewert von Funktionen
  • Currying zum teilweisen Anwenden von Funktionen (vor allem in Zusammenhang mit anonymen Funktionen interessant)
  • Funktionen zur Kombination von Funktionen zu größeren Einheiten (sehr schön z.B. in Parsern)
  • Monaden, zum sicheren Einbetten von Seiteneffekten in puren funktionalen Sprachen
  • Arrows, für sichere Nebenläufigkeit in puren funktionalen Sprachen
  • Unendliche Listen als Fassung von Reihen von Zahlen / Ereignissen. (Aktionen des Benutzers, Zufallszahlen, stetig genauer werdende Berechnungen einer Zahl...)
  • Continuations: Ein Konstrukt mit dem sich z.B. Exceptions und Coroutinen implementieren lassen
  • Coroutinen: Am einfachsten als eine Art Ultraleicht-Thread zu verstehen

Einige dieser Design Patterns werden auch in anderen Sprachen intensiv genutzt. Die Lambda-Abstraktion zum Beispiel spielt eine zentrale Rolle in Java, wenn man dort GUIs baut, da sie der ideale Callback sind. Also im Beispiel:

JButton button = new JButton("Titel");
button.addActionListener(new ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {
        // this is a lambda
    }
}

Gibt es noch mehr dieser Design Patterns? Funktionale Sprachen werden doch von jeder Menge Menschen benutzt...

Sind die irgendwo dokumentiert? Wenn nicht, dann muss ich mich wohl ranhalten und mein Verständnis selber aufschreiben.

Außerdem haben hochintegrierte Sprachen wie Lisp, Scheme, Smalltalk und Ruby noch ein weiteres Pattern, da sie sich besonders gut (oder überhaupt?) dazu eignen, Domänenspezifischen Subsprachen (DSL), also Sprachen die direkt in der Implementierungssprache eingebettet sind, zu formulieren. In Lisp bzw. Scheme ist das sogar die bevorzugte Vorgehensweise!

Mir ist allerdings noch nicht klar, welches Kriterium eine Sprache in die Lage versetzt, diese Integrierten DSLs besonders gut umzusetzen. Bisher dachte ich immer, dass dazu eine in ihrer Übersimplifizierung geniale Sprachdefinition - wie in Lisp und Smalltalk - notwendig ist, aber gerade das Beispiel von Ruby scheint dem zu widersprechen.