Funktionale Programmiersprachen An den Beispielen Haskell und Erlang Übersicht Programmiersprachen λ-kalkül Syntax, Definitionen Besonderheiten von funktionalen Programmiersprache, bzw. Haskell Objektorientierte Programmiersprachen Parallelisierung, Quantencomputer Beispiele
Was sind Programmiersprachen? Maschinencode Assembler imperarative Sprachen funktionale Sprachen Pascal, C, LISP, Haskell, Erlang, objektorientierte Sprachen Java, C++, Modula-2, λ-kalkül eingeführt von Alonso Church und Stephen Kleene in den 30er Jahren Definition einer berechenbaren Funktion vollständiges System zur Beschreibung und Ausführung mathematischer Berechnungen und Verfahren λ-notation: normal: f(x)= x 2 +2x+10 λ-notation: λ x : [x 2 +2x+10] Wertebereich, sogar Datentyp nicht festgelegt Ursprung und gemeinsamer Kern aller funktionalen Sprachen
Syntax Funktionen z.b.: quadrieren f ist gegeben durch die Funktion f: N! N; x a x 2 module Quad where quad :: Int -> Int quad = \x -> x*x Funktionenschreibweise f(x) = x 2 λ Notation λ x : x 2 module Quad where quad x = x*x Currying: Weglassen von Klammern Definitionen (Daten-)Typ Int, Float, String, Char, abstrakte Datentypen Funktion, Methode mathematische Funktionen Bedingungen max a b a>=b = a otherwise = b
Warum mathematische Formulierung? Wunsch Spezifikationen für Programme präziser zu machen, um eine Entsprechung zwischen dem Programm und seiner Spezifikation zu bekommen Erkenntnis, daß etwa 50 % der Arbeitsanstrengungen eines Programmierers in die Behebung von oft tiefsitzenden, schwer auffindbaren Fehlern der Programme gehen. Übersicht funktionale und imperative Sprachen Ein Programm ist eine Ein-/ Ausgaberelation. Diese Abbildung wird im Programmtext direkt (als Funktion) hingeschrieben. Programme sind zeitlos. Sie tun zu jeder Zeit das gleiche und hängen demnach nicht vom Zustand des Rechners ab. Die Formulierung von Programmen findet auf einem abstrakten, mathematisch orientierten Niveau statt. Ein Programm ist eine Arbeitsanweisung. Der Computer liefert zu den Eingabedaten die zugehörigen Ausgabedaten. Was ein Programmstück tut, hängt von Zustand des Rechners ab und kann sich demnach mit der Zeit ändern. Programme werden konkret auf Maschinen bezogen formuliert. Hat eher einen direkten Charakter.
Besonderheiten von funktionalen Programmiersprache pattern matching referenzielle Transparenz lazy evaluation higher order functions strong typing side-effects purity pattern matching Erkennung der passenden Funktion fac 0 = 1 fac n = n * fac n-1 fac n = if n == 0 then 1 else n * fac (n-1) Man nimmt an, daß ein Teil der Daten auf ein bestimmtes Muster passt
referenzielle Transparenz mathematische Variablen haben einen Wert. f(x) = sin x Wenn dieser Wert noch nicht berechnet wurde, ist diese Variable unbekannt und hat nicht irgendeinen anderen Wert. x := 0; Aufhebung des Unterschieds zwischen Funktion (Code) und Variablen (Daten), da die unbekannten Variablen eines Ausdrucks erst bekannt werden wenn der Ausdruck ausgewertet wird. Intuitive Programmierung Ausdrücke in Excel sind funktional Funktionsargumente Funktionale Programmierung ist intuitiv
lazy evaluation Grundsatz: nichts wird berechnet, bevor es benötigt wird z.b. Liste mit Primzahlen 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, definieren einer unendlichen Liste von Primzahlen, mittels Rekursion nur die die wirklich gebraucht werden, werden auch berechnet und zwar zu dem Zeitpunkt an dem sie gebraucht werden stellt sicher, daß nichts überflüssig berechnet wird HOT-higher order & typed Funktionen können andere Funktionen erzeugen higher order functions John Hughes: "A powerful name, for a powerful feature". Beispiel: differenzieren
higher order functions f(x)= x 3 +3 g(x)= x 2 +2 g (x)= differenzier g h (x)= differenzier (g+f) differenzier :: (Enum a, Num a) => a -> a differenzier x zipwith (*) (tail x) [1..] f x = x^3 +3 g x = x^2 +3 g x = differenzier g h x = differenzier (g+f) strong typing Keine Konvertierung von Typen möglich. Z.B. Int zu Double, oder pointer zu irgendwas Führt zu weniger Fehlern, da diese Fehler quelle ausscheidet Nur selten ist es wirklich notwendig In viele Programmiersprachen wird dies automatisch vom Compiler gemacht was zu schweren Fehlern führen kann.
side-effects Funktion ist nur durch die Eingabewerte bestimmt Änderung von Variablen von außen ist nicht möglich Demnach können sich variablen auch nicht ändern (wie in der Mathematik auch) Dadurch können Funktionen zu jeder Zeit und in jeder Reihenfolge im Programm ausgeführt werden und die Funktion wird trotzdem immer den gleichen Wert (bei gleichem Input zurückliefern) purity Im Gegensatz zu vielen anderen funktionalen Programmiersprachen ist Haskell rein Keine Ausnahmen bei side effects strong typing
Objektorientierte Programmiersprachen Abstraktion: Funktion der Interfaces, keine Offenlegung der Implementierung Kapselung: Information hiding, Objekte können den Zustand anderer Objekte nicht unerwartet ändern Polymorphie: Funktionen sind einem bestimmten Typ zugeordnet Vererbung: Objekte können das Verhalten existierender Objekte übernehmen und erweitern Parallelisierung früher war Umsetzung auf Computern extrem ineffizient durch Entwicklungen im Hardwarebereich, billigere Prozessoren Um die Rechenleistung eines Computersystems zu erhöhen, kann man parallel geschaltete Prozessoren einsetzen Programmiersprache darf dann nicht sequentiell aufgebaut sein. sondern so, daß die zu lösenden komplexen Problemstellungen so beschrieben werden, daß eine gleichzeitige Lösung der Problemstellungen möglich ist. Funktionale Programmiersprachen sind für den Einsatz von solchen parallel geschalteten Prozessoren sehr geeignet.
Eine letzte Eigenschaft von Haskell: Eleganz To put it simply: stuff just works like you'd expect it to. Beispiel Binomialkoeffizienten: Ã! Ã! n n 1 = + k k à n 1 k 1 binomial :: (Int Int) -> Int binomial n k n == k = 1 k == 0 = 1 otherwise = binomial (n-1) k + binomial (n-1) (k-1)!