Was bisher geschah I deklarative Programmierung I I I funktional: Programm: Menge von Termgleichungen, Term Auswertung: Pattern matching, Termumformungen logisch: Programm: Menge von Regeln (Horn-Formeln), Formel (Query) Auswertung: Unifikation, Resolution funktionale Programmierung (Haskell): I I I nebenwirkungsfrei lazy evaluation (ermöglicht unendliche Datentypen) kompakte Darstellung 14 Haskell-Programme Programm: Menge von Funktions-Definitionen Gleichungen zwischen Termen Ausdruck: Term Ausführung: Auswertung des Ausdruckes (Bestimmung seines Wertes) Pattern matching, Reduktion, (Termersetzung) Semantik: Funktion von Eingabe (Ausdruck) auf Ausgabe (Wert) I keine Variablen, also keine Programmzustände (kein Aufruf-Kontext) I Wert jeder Funktion(sanwendung) hängt ausschließlich von den Werten der Argumente ab 15 Syntax I Ausdrücke: Terme z.B. 2 + x * 7 oder double 2 I Funktionsdefinition: Gleichung zwischen zwei Ausdrücken z.B. inc x = x + 1 Programm: I I I Liste von Funktionsdefinitionen Ausdruck 16 Ausdrücke Ausdruck = Term (Baumstruktur) Jeder Ausdruck hat I einen Typ und I einen Wert Berechnung des Wertes durch schrittweise Reduktion (Termersetzung) 17 Beispiele Ausdruck 7 hat I den Typ Int I den Wert 7 Ausdruck 3 * 7 + 2 hat I den Typ Int I den Wert . . . Reduktion: rekursive Berechnung des Wertes 18 Funktionsdeklarationen double :: Int -> Int double x = x + x (Typdeklaration) (Funktionsdefinition) Ausdruck double 3 hat I den Typ Int I den Wert 6 Ausdruck double (double 3) hat I den Typ Int I den Wert . . . Ausdruck double hat I den Typ Int -> Int I den Wert x 7→ x + x (mathematische Notation) λx.(x + x) (λ-Kalkül) 19 Typinferenz Inferenzregel: f :: A → B e :: A f e :: B (man bemerke die Analogie zum Modus Ponens) Beispiel: True :: Bool False :: Bool neg :: Bool -> Bool neg b = case b of True -> False False -> True Typ von neg True, neg (neg True) sum [1,2,3] 20 Auswertung Normalform: nicht-reduzierbarer Ausdruck Auswertung: schrittweise Reduktion, bis Normalform erreicht Auswertungsstrategien: innermost-Reduktion (strikt) outermost-Reduktion (lazy) Beispiel: double (double 3) Besonders in Haskell: I Termination I Auswertungsreihenfolge egal (Konfluenz) 21 Definition von Funktionen Programmstrukturen: I Fallunterscheidung I Rekursion Beispiel: fac n = if n < 1 then 1 else n * (fac (n-1)) zum Vergleich: Ablaufsteuerung in imperativen Sprachen I Nacheinanderausführung I Verzweigung (Fallunterscheidung) I Wiederholung (Iteration) 22 Funktionen als Daten f :: Int -> Int f x = 2 * x + 3 äquivalent: Lambda-Ausdruck f = λx.(2x + 3) Funktionsanwendung (Reduktion): f = λx.A fB = A[x 7→ B] falls x nicht (frei) in B vorkommt Lambda-Kalkül: Alonzo Church 1936, Henk Barendregt 1984 Beispiel: A = 2x + 3, B = 1 f = λx.A = λx.(2x + 3) fB = (λx.A)B = λx.(2x + 3)1 = 2·1+3=5 23 Rekursion und Pattern Matching fac :: Int -> Int fac 1 = 1 fac n = n * (fac (n-1)) Wert von fac 4 ? Wert von fac (-4) ? Verbesserungsvorschlag ? alternative Darstellung: fac :: Int -> Int fac n = if (n > 1) then n * (fac (n-1)) else 1 noch viel mehr: http: //www.willamette.edu/~fruehr/haskell/evolution.html 24