Funktionale Programmiersprache

Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 16. Dezember 2003 um 20:28 Uhr durch ApeBot (Diskussion | Beiträge) ((Bot) HTML 2 wiki). Sie kann sich erheblich von der aktuellen Version unterscheiden.

In einer funktionalen Programmiersprache werden Programme (im wesentlichen) als (Mengen von) Funktionsdefinitionen dargestellt. Dementsprechend stellt sich die Ausführung eines solchen Programms als Auswertung eines Terms dar. Somit kann man funktionale Programmiersprachen als Implementationen des Lambda-Kalküls betrachten, in dem Funktionsdefinition (lambda-Abstraktion) und Funktionsanwendung die entscheidenden Sprachelemente sind. (Ggs.: imperative Programmiersprache)

Anders ausgedrückt:

  • ein funktionales Programm ist eine Ein-/Ausgaberelation, d.h. eine Abbildung von Eingabedaten auf Ausgabedaten (die im Programmtext explizit dargestellt wird), wohingegen ein imperatives Programm eine Arbeitsanweisung für eine Maschine ist. (Pepper)
  • daraus folgt ein sehr wichtiger Unterschied: in einem funktionalen Programm wird die Reihenfolge der Verarbeitungsschritte nicht expliziert (für Probleme und Ausnahmen s.u.), während ein imp. Programm ohne die Reihenfolge der Abarbeitungsschritte gar nicht verstanden werden kann.
  • Funktionale Programmierung ist i.d.R. abstrakter.

Konzepte

Da funktionale (Teil-)Programme als Funktion aufgefasst werden können, hat ein Ausdruck während der Programmausführung immer den gleichen Wert. Man bezeichnet diese Eigenschaft als Werttreue (engl. referential transparency). Das ist ein großer Unterschied zur imp. Programmierung, wo eine Variable durch Zuweisung ihren Wert ändern kann. Derlei Nebenwirkungen sind in der funktionalen Programmierung nicht möglich, was große Vorteile für das Beweisen von Algorithmen oder die Parallelisierung von Programmen mit sich bringt. Da durch diese Einschränkung keine Iteration (wie z.B. mit for-Schleifen in C) möglich ist, müssen viele Probleme durch Rekursion gelöst werden.

Man unterscheidet Sprachen erster Ordnung und Sprachen höherer Ordnung. Im Gegensatz zu Sprachen erster Ordnung betrachtet man bei denen höherer Ordnung Funktionen selbst als Werte. Dies erlaubt es insbesondere, Funktionen als Ergebnisse oder Parameter anderer Funktionen zu verwenden. Ein typisches Beispiel ist map, um eine beliebige, übergebene Funktion f auf jedes Element einer Liste anzuwenden. Definition in Haskell:

map f [] = []
map f (x:xs) = f x : map f xs
In der ersten Zeile wird das Ergebnis für eine leere Liste zurückgegeben; die zweite Zeile wendet die Funktion f auf das erste Listenelement an und führt dann einen Rekursionsschritt für die restliche Liste durch.

Funktionale Sprachen kann man auch nach ihrer Auswertungsstrategie unterscheiden: bei strikter Auswertung (engl. eager bzw. strict evaluation) werden die Argumente einer Funktion ausgewertet, bevor die Funktion selbst aufgerufen wird. Dem gegenüber steht die Bedarfsauswertung (engl. lazy evaluation), bei der Argumente erst ausgewertet werden, wenn deren Wert benötigt wird. Dadurch lassen sich insbesondere Ausdrücke mit unendlichen Werten definieren, was z.B. sinnvoll sein kann für einen Algorithmus, der alle Primzahlen berechnet. Dennoch ist strikte Auswertung in der Regel effizienter.

Weiterhin kann man funktionale Sprachen einteilen in dynamisch und statisch typisierte Sprachen, die sich dadurch ergeben, dass die Typprüfung während der Laufzeit bzw. während der Übersetzungszeit stattfinden kann. Alle funktionalen Sprachen sind stark typisiert, so dass Typfehler grundsätzlich erkannt werden.

Ein Beispiel in SML

local
  val pi = 3.14;
  val sq = fn x => x*x;
in
  val ringarea = fn (R,r) => pi*(sq R - sq r);
end;
Dieses Programm definiert eine Funktion ringarea, die die Fläche berechnet, welche zwischen den beiden konzentrischen Kreisen mit den Radien R und r liegt. Dazu werden die Konstante pi und die Hilfsfunktion sq definiert. Diese werden von ringarea dann für die Berechnung benutzt.


Beispiele für funktionale Programmiersprachen