Während meiner Teilnahme an der QCon San Francisco hatte ich das besondere Vergnügen, einem ganzen Track beizuwohnen, der dem Bereich der funktionalen Programmierung gewidmet war, einem Thema, das mich zutiefst interessiert. Nachdem ich den Track verfolgt habe, bin ich noch mehr als zuvor davon überzeugt, dass funktionale Programmierung nicht auf die akademische Welt beschränkt ist. Ich denke, dass sie in den nächsten Jahren einen tiefgreifenden Einfluss auf unsere geistige Perspektive und die Art und Weise haben wird, wie wir über Programmierung und Problemlösung denken. In diesem Blog werde ich die Sessions, die ich verfolgt habe, zusammenfassen, Ihnen ein paar Denkanstöße geben, die ich mitgenommen habe, und Sie hoffentlich dazu bringen, über Ihren Programmierstil nachzudenken.
Der Track begann mit einer eher ungewöhnlichen Kombination: einem Vortrag von Paul Hudak über Haskell und die Künste.
Er sprach über das Konzept der funktionalen reaktiven Programmierung (FRP), die heute ein wichtiger Forschungsbereich an der Universität Yale ist. FRP ist ein Programmierstil, bei dem jede Funktion eine zeitlich veränderliche Größe erfassen kann (z.B. Eingangston, Video, Benutzeraktionen). Diese Art der Programmierung findet Anwendung in der Robotik, der parallelen Programmierung und der Audioverarbeitung. Immer wenn eine Funktion einen neuen Eingabewert erhält, wird sie neu ausgewertet und eine neue Ausgabe zurückgegeben. In seinem Vortrag stellte er insbesondere HasCore und HasSound vor, domänenspezifische Sprachen, die für Musik und Klangsynthese entwickelt wurden. Paul sagte, dass funktionale Sprachen besonders gut für Computermusik geeignet sind, da sie deklarativ sind (sie sagen, 'Was' getan werden soll, anstatt 'Wie' es getan werden soll). Die Abstraktionsmechanismen von Haskells ermöglichen elegante, präzise und leistungsstarke musikalische Programme, die die Mechanismen der faulen Auswertung, Funktionen höherer Ordnung, algebraische Datentypen und Typklassen nutzen. Ein grundlegendes Beispiel für die Modellierung von Musik in Haskell finden Sie hier.Der nächste Vortrag wurde von Lennart Augustsson zu einem ganz anderen Thema gehalten, das jedoch nicht weniger interessant war: die Implementierung von domänenspezifischen Sprachen in Haskell. Es hat den Anschein, dass ein Haskell-Programmierer jedes Mal, wenn er das Thema DSL erwähnt, ein schiefes Lächeln auf sein Gesicht zaubert, da dies in Haskell schon seit Ewigkeiten gemacht wird und es für ihn schwer zu verstehen ist, warum es derzeit so ein Hype ist.
Lennart gab ein paar Beispiele, die er selbst durch die Implementierung von DSLs in Haskell entwickelt hatte. Am auffälligsten war für mich der Fall, in dem er eine DSL für die Generierung von Excel implementiert hatte (d.h. die echten Excel-Blätter, nicht nur eine textbasierte csv-Datei). Wie er feststellte, verfügt Excel über einen eher rudimentären Abstraktionsmechanismus, der nur aus der Wiederverwendung von Kopien und Vergangenheit besteht. Es wird jedoch von vielen Geschäftsleuten verwendet und ist eine vertraute Benutzeroberfläche. Daher besteht die Lösung darin, Excel-Blätter zu erzeugen. Lennart ist ein Verfechter einer starken Typüberprüfung, um Fehler bei der Kompilierung zu vermeiden. Er zeigte, wie er Haskells-Typklassen und auch ein eher obskures Konzept wie Phantom-Typen in seiner Excel-DSL verwendet hat. Das Ergebnis war eine DSL, die in der Lage war, Excel-Tabellen zu generieren, ohne Typfehler bei Operationen zuzulassen, wie z.B. das Hinzufügen von zwei Zellen in Excel, von denen eine eine Ganzzahl und die andere einen String enthält, was Excel selbst nicht verhindert. In der Tat eine interessante und auch amüsante Sitzung, die die volle Leistungsfähigkeit des Haskell-Typensystems aufzeigte und eine Anwendung in einem Bereich demonstrierte, der einem wahrscheinlich nicht direkt in den Sinn kommt, wenn man an Haskell denkt.Ein den meisten von uns vielleicht vertrauteres Konzept wurde in einer Sitzung von David Pollak vorgestellt. Er sprach über eine Webanwendung, Buy a feature, die er kürzlich entwickelt hatte. Ein Thema, das vielleicht nicht sofort das Interesse der meisten weckt, aber David hatte Scala und das Scala Web-Framework Lift verwendet, das er selbst entwickelt hatte. Er verwendete funktionale Programmierparadigmen, einschließlich der Actor-Bibliothek von Scala, um ein webbasiertes, ernsthaftes Spiel für mehrere Benutzer in Echtzeit zu implementieren. Wie er sagte, verwendete das Team zunächst den imperativen Programmierstil von Java. Nach einiger Zeit (und mit Hilfe von Coaching) gingen sie jedoch allmählich dazu über, den deklarativen, funktionalen Programmierstil zu verwenden, den auch Scala bietet. Einige weitere bemerkenswerte Aussagen waren, dass keiner der in der Anwendung gefundenen Fehler mit Gleichzeitigkeit zu tun hatte. Offensichtlich hat ihm der ereignisgesteuerte, nachrichtenübermittelnde Programmierstil, der die Actor-Bibliothek von Scala verwendet, gute Dienste geleistet.
Außerdem erklärte er, dass die Anzahl der Unit-Tests, die er benötigte, um dieses System bequem in Produktion zu bringen, erheblich geringer war (in der Größenordnung von 30%, wenn ich mich recht erinnere), verglichen mit dem Umfang der Testabdeckung, die bei der Verwendung von Ruby und Rails erforderlich war, die er ebenfalls ausgiebig verwendet hat. Eine interessante Fallstudie und eines der ersten Beispiele aus der realen Welt für den Einsatz von Scala, von denen ich gehört habe. Wenn Sie daran interessiert sind, lesen Sie Davids Blog ), um mehr über dieses Thema zu erfahren.
Das Ende des Tages hätte für einen Anhänger der funktionalen Programmierung nicht viel besser sein können.
Eric Meijer selbst schloss den Tag mit einem reizvollen Vortrag mit dem Titel 'The fundamentalist functionalist programming'. Sein zum Nachdenken anregendes Argument ist, dass wir uns in der Art und Weise, wie wir programmieren, in den letzten Dutzenden von Jahren in die falsche Richtung bewegt haben und dass es an der Zeit ist, einen Richtungswechsel vorzunehmen. Wie der Titel dieses Blogs andeutet, wenden wir uns der reinen, grundlegenden funktionalen Programmierung zu.
Warum sollte das eine gute Sache sein? Jeder 'reine' funktionale Code hat keine Seiteneffekte und verändert daher auch nicht den Zustand. Da der Zustand nicht verändert wird, spielt die Reihenfolge, in der die Anweisungen ausgeführt werden, keine Rolle, ebenso wenig wie die Anzahl der Programmausführungen. Das macht Programme besser verständlich und weit weniger fehleranfällig. Wie unangenehm ein impliziter Nebeneffekt einer Funktion sein kann, hat Eric anhand eines Beispiels aus der Sprache C# gezeigt. Es würde diesen Blog zu sehr in die Länge ziehen, ins Detail zu gehen, daher sollte der interessierte Leser einen Blick in seinen Blog werfen.
Viele werden jetzt denken: 'keine Seiteneffekte, also kein Nutzen', vor allem, wenn man an die IO denkt, die immer irgendwelche Seiteneffekte verursacht. Tatsächlich war Erics Hauptargument gegen die fundamentalistische funktionale Programmierung nicht, dass alle Seiteneffekte schlecht sind. In der Tat argumentierte er, dass jedes Programm Nebenwirkungen haben kann und dass Nebenwirkungen sogar etwas Gutes sind. Sein Hauptargument war jedoch, dass alle Seiteneffekte in der Sprache explizit gemacht werden sollten. Es sind die impliziten Seiteneffekte, die in Funktions- oder Methodenaufrufen versteckt sind, die zu überraschenden und unerwarteten Ergebnissen und in der Folge zu langwierigen Debugging-Sitzungen führen. Selbst Erlang ist keine 'reine' funktionale Sprache im fundamentalistischen Sinne, da sowohl IO-Operationen als auch das Spawnen eines neuen Prozesses Seiteneffekte haben, die in der Sprache implizit sind.
Die Sprache, an deren Entwicklung Eric beteiligt war, Haskell, ist natürlich die Sprache, für deren Verwendung er plädiert, und wenn nicht die Sprache selbst, so doch zumindest ihre Ideen. In Haskell werden alle Seiteneffekte in monadischen Klassen kodiert. Eric gab ein einfaches Beispiel für dieses Konzept und erklärte, dass eine Monade einfach als eine Sammlung von Werten von Dingen verstanden werden kann, die sich ändern. Er verglich eine Uhr mit einer Monade, bei der die Uhrzeit jedes Mal einen anderen Wert hat, wenn Sie auf sie schauen. Die Uhr selbst ändert sich nicht, aber der Wert, den sie repräsentiert, schon. Monadische Klassen können an Funktionen weitergegeben werden, ohne dass die Seiteneffekte der monadischen Klasse selbst entgehen können. Durch die Verwendung dieses Mechanismus ist sofort ersichtlich, welche Teile eines Programms tatsächlich den Zustand ändern, und das macht Programme leichter verständlich.
Man könnte meinen, dass diese Konzepte nur noch von akademischem Interesse sind. Wie Eric jedoch gezeigt hat, gibt es sie bereits in LINQ, der sprachintegrierten Abfrage von .NET, die monadische Klassen und eine verzögerte Auswertung verwendet. Wenn Sie also ein C#-Programmierer sind, haben Sie bereits mit diesen funktionalen Konzepten zu tun. C# integriert mehr und mehr funktionale Funktionen in die Sprache.
Ein sehr nachdenklich stimmender Vortrag, der mich zum Nachdenken darüber gebracht hat, warum nicht die ganze Welt einen funktionalen Programmierstil verwendet. Nach diesem Tag bin ich jedoch davon überzeugt, dass die funktionale Programmierung sehr lebendig ist und dass wir sie und ihre Ideen in unserer täglichen Arbeit immer häufiger einsetzen werden. Ich denke, wir müssen uns diese Ideen zu eigen machen, um sie bei der Problemlösung voll auszuschöpfen und letztendlich bessere Programme zu schreiben.