Funktionale Programmierung: Die Definition

Funktionale Programmierung ist schnell definiert. Funktionale Programmierung ist die Programmierung mit mathematischen Funktionen. Ist das schon der ganze Artikel? Natürlich nicht!

 

Mathematische Funktionen

Funktionale Programmierung ist die Programmierung mit mathematischen Funktionen. Du ahnst es vermutlich. Entscheidend an dieser Definition ist der Ausdruck mathematische Funktionen. Mathematische Funktionen sind Funktionen, die immer das gleiche Ergebnis zurückgeben, wenn sie mit den gleichen Argumenten aufgerufen werden. Daher verhalten sie sich wie unendlich große Lookup-Tabellen.

Referenzielle Transparenz

Die Eigenschaft, dass eine Funktion immer das gleiche Ergebnis zurückgibt, wenn sie die gleichen Argumente verwendet, wird als Referenzielle Transparenz bezeichnet und besitzt weitreichende Konsequenzen:

  • Mathematische Funktionen können keine Seiteneffekte besitzen und damit Zustand außerhalb des Funktionskörpers verändern.
  • Der Funktionsaufruf kann durch sein Ergebnis ersetzt, umsortiert oder automatisch auf einen anderen Thread verschoben werden.
  • Der Programmfluss wird durch die Datenabhängigkeiten und nicht durch die Reihenfolge der Anweisungen vorgegeben.
  • Mathematische Funktionen können deutlich einfacher refaktoriert und getestet werden, da die Funktionen isoliert betrachtet werden können.

Das hört sich doch vielversprechend an. Die Referenzielle Transparenz einer mathematischen Funktion besitzt aber auch massive Einschränkungen. Mathematische Funktionen können nicht mit der Außenwelt kommunizieren. Beispiele gefällig?

  • Mathematische Funktionen können keine Benutzereingabe oder Dateien verarbeiten.
  • Sie können ihre Ausgabe weder auf die Konsole noch in eine Datei schreiben.
  • Zufallsfunktionen oder Zeitfunktionen, die immer ein anderes Ergebnis produzieren, können keine mathematischen Funktionen sein.
  • Eine mathematische Funktion kann keinen Zustand aufbauen.

Die Definition der funktionalen Programmierung mit Hilfe von mathematischen Funktionen ist kurz und knackig, hilft aber nicht wirklich weiter. Die entscheidende Frage steht noch im Raum. Wie lässt sich mit funktionaler Programmierung etwas Vernünftiges programmieren? Sind doch mathematische Funktionen wie isolierte Inseln, die keine Kommunikation mit der Außenwelt zulassen. Oder um es in den Worten von Simon Peyton Jones, einem der Väter von Haskell zu formulieren. Den einzigen Effekt, den mathematische Funktionen besitzen können, ist das Zimmer aufzuwärmen.

Nun werde ich ein weniger weiter ausholen. Worin zeichnen sich funktionale Programmiersprachen aus?

Charakteristiken funktionaler Programmiersprachen

Bei meiner Tour durch die Charakteristiken funktionaler Programmiersprachen wird mir Haskell wertvolle Dienste erweisen.

Haskell

Haskell bietet sich vor allem aus zwei Gründen an:

  1. Haskell ist eine rein funktionale Programmiersprachen und somit lassen sich Charakteristiken der funktionalen Programmierung sehr schön an ihr studieren.
  2. Haskell ist die wohl einflussreichste Programmiersprache der letzten 10 - 15 Jahre. 

Die zweite Aussage kann ich natürlich nicht so im Raume stehen lassen. Für Python und insbesondere C++ werde ich die Aussage mit den nächsten Artikel reichlichst belegen. Daher ein paar Worte zu Java, Scala und C#.

  • Philip Wadler, ein weiterer Vater von Haskell, war bei der Implementierung von Generics in Java beteiligt.
  • Martin Odersky, Vater von Scala, das viele Impulse aus Haskell annahm, war ebenfalls bei der Implementierung von Generics in Java beteiligt.
  • Erik Meijer ist ein glühender Verehrer und Forscher rund um Haskell. Die Haskell Konzepte der Monaden hat er in der sehr häufig verwendeten C# Bibliothek LINQ umgesetzt.

Ich gehe noch ein Schritt weiter. Wer funktionale Programmierung und vor allem Haskell gut versteht, weiß, wie sich in den nächsten Jahren die Programmiersprachen entwickeln. Selbst so rein objekt-orientierte Sprachen wie Java konnten dem Druck der funktionalen Ideen mit Generics und nun auch Lambda Ausdrücken nicht widerstehen.

Nun aber zurück zum eigentlichen Thema. Worin zeichnen sich funktionale Programmiersprachen aus?

Charakteristiken

Bei meiner Suche nach den Charakteristiken habe ich 7 typische Punkte identifiziert. Diese müssen nicht alle Charakteristiken sein und sie müssen auch nicht auf alle funktionalen Programmiersprachen zutreffen. Die Charakteristiken helfen aber, die abstrakte Definition der funktionalen Programmierung durch mathematischen Funktionen mit Fleisch zu füllen.

 CharakteristikenFunktionaleProgrammierung

Die Graphik stellt einerseits die Charakteristiken der funktionalen Programmierung dar, andererseits gibt sie meine Gliederung für die nächsten Artikel vor. Diese werde ich mit vielen Beispielen aus Haskell, C++ und auch Python veranschaulichen. Doch für welche Techniken stehen die sieben Charakteristiken?

First-Class Funktionen sind typisch für funktionale Programmiersprachen. Diese Funktionen können Funktionen als Argumente annehmen oder Funktionen als Argumente zurückgeben. Dazu müssen sie Funktionen höherer Ordnung sein, das heißt, sich wie Daten verhalten. Reine Funktionen liefern immer das gleiche Ergebnis, wenn sie mit den gleichen Argumenten aufgerufen werden und können keine Seiteneffekte besitzen. Sie sind der Grund dafür, das Haskell als eine rein funktionale Programmiersprache bezeichnet wird. Rein funktionale Programmiersprachen kennen keine veränderliche Daten, daher kann es in ihnen keine while- oder for-Schleifen geben, die auf einem Schleifenzähler basieren. Anstelle der while- oder for-Schleife kommt in rein funktionalen Programmiersprachen Rekursion zum Einsatz. Die augenfälligste Charakteristik der funktionalen Programmierung ist es, dass sich Funktionen sehr leicht komponieren lassen. Das ist vor allem darin begründet, dass die Liste die zentrale Datenstruktur der funktionalen Programmierung ist. Wertet ein Ausdruck seine Argumente sofort aus, wird dies als greedy oder auch eager evaluation bezeichnet. Werden die Argumente hingegen erst dann ausgewertet, wenn diese benötigt werden, kommt Bedarfsauswertung oder auch lazy evaluation zum Einsatz. Bedarfsauswertung spart dann Zeit und Speicher, wenn der Ausdruck nicht vollständig auswertet werden muss oder das Ergebnis eines Ausdrucks nicht benötigt wird. Vermutlich ahnst du es bereits. Die klassischen Programmiersprachen sind gierig. Sie werten ihre Ausdrücke sofort aus.

Wie geht's weiter? 

Los geht es in meinem nächsten Artikel mit First-Class Funktionen, die in C++ schon lange zu Hause sind.

 

 

 

 

 

 

 

 

 

title page smalltitle page small Go to Leanpub/cpplibrary "What every professional C++ programmer should know about the C++ standard library".   Hole dir dein E-Book. Unterstütze meinen Blog.

 

Mentoring

Stay Informed about my Mentoring

 

Rezensionen

Tutorial

Besucher

Heute 1991

Gestern 3725

Woche 7792

Monat 35109

Insgesamt 3887823

Aktuell sind 587 Gäste und keine Mitglieder online

Kubik-Rubik Joomla! Extensions

Abonniere den Newsletter (+ pdf Päckchen)

Beiträge-Archiv

Sourcecode

Neuste Kommentare