Funktionale Sprachen - Was, Wie, Warum?
Funktionale Sprachen - Was, Wie, Warum?
-
Ursprung: Lisp = Überlegungen aus der Theorie der Berechenbarkeit praktisch machen;
- Anwendungen zunächst beschränkt auf künstliche Intelligenz und Hochschulen;
- seit den 70er Jahren neues und wachsendes Interesse an funktionaler Programmierung;
- Entwicklung von Sprachen, die durch angebotene Mittel und Implementierung auf Softwaretechniker allgemein zielen.
-
Gründe:
- 1.
- Kritik an imperativen Sprachen:
Semantik (Wirkung, Verständnis vom Programm) durch sich in der Zeit ändernden Zustand (Stand der Bearbeitung, Variablenbelegung) gegeben - und das ist zu schwer für das menschliche Hirn!
Beispiel: Partitionierung in Quicksort:
i:=links; j:=rechts-1;
loop
while a(i)<trenn loop i:=i+1; end loop;
while a(j)>trenn loop j:=j-1; end loop;
if i>=j then exit; end if;
temp:=a(i); a(i):=a(j); a(j):=temp;
i:=i+1; j:=j-1;
end loop;
?? Was gilt hier ??
?? Kommt man überhaupt dahin ??imperative Programmierung ist mühsam, logisch anspruchsvoll und fehleranfällig, denn:
- Verhältnis von Zuweisung ``:='' und mathematischer Gleichheit ``='' ist (nicht nur für Anfänger) problematisch,
- zwar reichliche Verwendung von Ausdrücken in den Anweisungen, aber wegen mangelnder referentieller Transparenz (Kontextabhängigkeit) großer Unterschied zu üblicher (mathematischer) Interpretation, z.B.:
i: integer := 1;
a: array(1..10) of integer := (others=>0);
function f return integer is - Seiteneffekt
begin i:=i+1; return i; end f;
dann z.B.:
i:=i+f;
a(i):=f;
a(f):=a(f);
a(i+f):=i+f;
if 2*(i+f)=(i+f)+(i+f) then ...
...
Klar: Ziel nicht, Reihenfolge der Auswertung in Gebilden wie ``a(f):=a(f)'' zu normieren, sondern das Problem zu vermeiden!
- 2.
- positive Beiträge funktionaler Programmierung: andere Formen von Abstraktion & Modularisierung
- Funktionen als "`Bürger erster Klasse"', also z.B.:
- Vektor von Funktionen,
- Funktion als Ergebnis und Parameter anderer Funktionen
"`higher order functions"'
vgl. "`map"', "`fold"' in Programmieren II
vgl. Mathematik:
Differentiation als Transformation von reellen Funktionen, also:
diff :: (Float->Float) -> (Float->Float)
diff(sin) = cos
ist in funktionaler Programmierung numerisch ohne weiteres machbar!
- verzögerte Auswertung ("`lazy evaluation"') = rechne nur soviel, wie für das gewünschte Ergebnis nötig.
effiziente Kombination vom Programmteilen, die ohne Rücksicht auf spezifische (beschränkte) Anwendung entworfen sind.
Beispiel: Test ob Zahl n prim ist Annahme:
es gebe Funktion divisors :: Int -> [Int] die Liste aller Teiler einer gegebenen Zahl liefert dann:
is_prim n = divisors n == [1,n] wobei:
falls n keine Primzahl ist wird divisiors nur solange ausgewertet, bis erstes Gegenbeispiel gefunden wurde. also: Abbruchbedingung für divisors implizit, also divisors für ganz verschiedene Zwecke nutzbar (vgl.: wie macht man das in imperativer Programmierung ?? ) Ferner: lazy evaluation erlaubt Arbeit mit (potentiell) unendlichen Datenstrukturen (Listen, Bäumen, ...).
- Funktionen als "`Bürger erster Klasse"', also z.B.:
Next:HaskellUp:EinführungPrevious:Überblick "`Höhere Programmiersprachen"' Ronald Blaschke
1998-04-19