Grundlagen der Programmierung 2 Prof. Dr. Manfred Schmidt-Schauß Künstliche Intelligenz und Softwaretechnologie 17. April 2013 Grundlagen der Programmierung 2: Geplanter Inhalt der ersten Hälfte • • • • • • • rekursives Programmieren in Haskell Auswertung in Haskell Programmieren mit Listen Datenstrukturen: Bäume Polymorphe Typen und Typklassen Compilerbau; ◦ Lexer ◦ Parser ◦ Kombinator-Parser ◦ Kode-Erzeugung; abstrakte Maschinen ◦ Shift-Reduce Parser und Compiler-Generatoren ◦ Compiler-Generatoren (Semantik) Grundlagen der Programmierung 2 (1.A) - 2 - Bücher, Literatur, URLs Haskell und funktionale Programmierung: • http://www-stud.informatik.uni-frankfurt.de/˜prg2 insbesondere das Skript zur Vorlesung • www.haskell.org • http://haskell.org/onlinereport/ • • • • Compiler: • • Haskell-Web-Seite Haskell-Doku Manuel Chakravarty und Gabriele Keller, Einführung in die Programmierung mit Haskell Richard Bird, Introduction to Functional Programming Using Haskell Simon Thompson, Haskell: The Craft of Functional Programming Graham Hutton, Programming in Haskell (2007) Jeffrey D. Ullman, Monica S. Lam, Ravi Sethi , Alfred V. Aho Compilers: Principles, Techniques, and Tools , 2nd Edition, Pearson 2006 deutsch: Compiler: Prinzipien, Techniken und Werkzeuge, Pearson Studium, 2008 Niklaus Wirth, Grundlagen und Techniken des Compilerbaus, Oldenbourg 1997 Grundlagen der Programmierung 2 (1.A) - 3 - Haskell rekursive Programmierung mit einer stark typisierten funktionalen Programmiersprache mit parametrischem Polymorphismus Haskell Grundlagen der Programmierung 2 (1.A) - 4 - Haskell Haskell ist eine moderne Programmiersprache; sehr weitgehende Konzepte werden erprobt und kombiniert • • strenge und statische Typisierung Nicht-strikte Auswertung ⇒ ⇒ • viele korrekte Programmtransformationen korrekte automatische Parallelisierung Prozess-Programmierung und Konkurrente Auswertung ⇒ deklarative Programmierung Grundlagen der Programmierung 2 (1.A) - 5 - Haskell Wichtige Eigenschaften funktionaler Programmiersprachen Referentielle Transparenz Gleiche Funktion, gleiche Argumente =⇒ gleicher (Rückgabe-)Wert Keine Seiteneffekte! D.h. keine Änderung von Objekten Verzögerte Auswertung Nur die für das Resultat notwendigen Unterausdrücke werden (so spät wie möglich) ausgewertet. Parametrisch Polymorphes Typsystem Nur Ausdrücke mit Typ sind erlaubt — es gibt Typvariablen. Das Typsystem garantiert: keine dynamischen Typfehler. Automatische Speicherverwaltung Anforderung und Freigabe von Speicher Grundlagen der Programmierung 2 (1.A) - 6 - PR zu Funktionalen Programmiersprachen OCaml: Variante von ML, eine Programmiersprache analog zu Haskell. Aus dem Artikel von Yaron Minsky und Stephen Weeks: (JFP 2008) Immutability wird gelobt: entspricht Verzicht auf Zuweisungen Pattern Matching wird gelobt: entspricht Datentypen mit Konstruktoren und case-Expressions Tail-Rekursions-Optimierung) wird vermisst. ( kommt noch) Grundlagen der Programmierung 2 (1.A) Das gibt es in Haskell - 7 - Programmierung in Haskell Grundprinzipien: des funktionalen Programmierens • • • • Definition von Funktionen Aufbau von Ausdrücken: Anwendung der Funktion auf Argumente, die wieder Ausdrücke sein können. programminterne Kommunikation: Nur der Wert von Ausdrücken wird bei der Auswertung zurückgegeben. Funktionen können Datenobjekte sein Grundlagen der Programmierung 2 (1.A) quadrat x = x*x 3*(quadrat 5) 75 - 8 - Standards zu Folien und Skript Darstellung von Quell-Code (Source-code) auf den Folien und Skript: quadrat x = x*x Darstellung von Interpreteraktionen auf Folien und Skript: *Main> 2+2 ←4 Grundlagen der Programmierung 2 (1.A) - 9 - Interpreter / Compiler für Haskell Wir verwenden den Interpreter GHCi www.haskell.org Einfacher Download und Installation Siehe Hilfestellungen auf der Professur-Webseite. Simon Peyton Jones und Simon Marlow ( Microsoft Research) die wichtigsten Forscher und Weiterentwickler des GHC: (Glasgow Haskell Compiler). (März 2013: Simon Marlow wechselt zu Facebook.) Grundlagen der Programmierung 2 (1.A) - 10 - Umgang mit dem Interpreter Online-Report Aufruf: http://www.haskell.org/onlinereport ghci (im richtigen Fenster) prompt > ghci ←< Einige Zeilen Infos > Prelude> :h ←< Hilfe-Menu > Prelude> :t True ←True :: Bool (druckt den Typ des Ausdrucks True) (Option s für Statistik gesetzt) Prelude> :set +s ←- Module im Interpreter verwenden: Prelude> :m +Char +Numeric ←Grundlagen der Programmierung 2 (1.A) - 11 - Einfache Daten und Operatoren • ganze Zahlen • • • • • beliebig lange ganze Zahlen rationale Zahlen Gleitkommazahlen Zeichen Datenkonstruktoren 0,1,-3 Typ: Int n mit |n| ≤ 231 − 1 = 2147483647 11122399387141 Typ: Integer, 3%7 Typ: Ratio 3.456e+10 Typ: Floating ’a’ Typ: Char True, False Typ: Bool Diese nennen wir auch Basiswerte (bis auf Floating) Grundlagen der Programmierung 2 (1.A) - 12 - Einfache Daten und Operatoren • Arithmetische Operatoren: (ein) Typ: Int → Int → Int +, −, ∗, /, • Arithmetische Vergleiche: (ein) Typ: Int → Int → Bool ==, <=, < . . . • Logische Operatoren: (ein) Typ: Bool → Bool → Bool &&, ||, not Grundlagen der Programmierung 2 (1.A) - 13 - Beispiel Definition eines Polynoms, z.B.: x2 + y 2: quadratsumme x y = quadrat x + quadrat y Auswertung: ... *Main> quadratsumme 3 4 ←25 Grundlagen der Programmierung 2 (1.A) - 14 - Typen in Haskell TYP Integer -> Integer -> Ausdruck Integer -> Integer -> Integer -> Int Integer Float Double Integer Integer Integer Typ (Typ von Argument 1) -> (Typ von Argument 2) -> Ergebnistyp Grundlagen der Programmierung 2 (1.A) 3 123 1.23e45 1.23e45 (+) quadrat quadratsumme Konstanten, Funktionen - 15 - Typen in Haskell Beispiel Die Ausgabe des Interpreters für die Addition (+) ist komplizierter: Prelude> :t (+) ←(+) :: (Num a) => a -> a -> a D.h.: Für alle Typen a, die man als numerisch klassifiziert hat, d.h. die in der Typklasse Num sind, hat (+) den Typ a -> a -> a Z.B. gilt: (+)::Integer -> Integer -> Integer (+)::Double -> Double -> Double Grundlagen der Programmierung 2 (1.A) - 16 - (vereinfachte) Haskell-Syntax hFunktionsDefinitioni ::= hFunktionsnameihParameteri∗ = hAusdrucki hAusdrucki ::= hBezeichneri | hZahli | (hAusdrucki hAusdrucki) | (hAusdrucki) | (hAusdruckihBinInfixOpi hAusdrucki) hBezeichneri ::= hFunktionsnamei | hDatenkonstruktornamei | hParameteri | hBinInfixOpi hBinInfixOpi ::= ∗ | + | − | / Argumente einer Funktion: Anzahl der Argumente: formale Parameter. Stelligkeit der Funktion: (ar(f )) Die Nichtterminale hFunktionsnamei, hParameteri, hBezeichneri, hDatenkonstruktornamei sind Namen (z.b. quadrat“) ” Grundlagen der Programmierung 2 (1.A) - 17 - Aus der Haskell-Dokumentation http://www.hck.sk/users/peter/HaskellEx.htm http://www.haskell.org/onlinereport/exps.html#sect3.2 exp10 -> \ apat1 ... apatn -> exp | let decls in exp | if exp then exp else exp | case exp of { alts } | do { stmts } | fexp fexp -> [fexp] aexp aexp -> qvar | gcon | literal | ( exp ) | ( exp1 , ... , expk ) | [ exp1 , ... , expk ] | [ exp1 [, exp2] .. [exp3] ] Grundlagen der Programmierung 2 (1.A) (lambda abstraction, n>=1) (let expression) (conditional) (case expression) (do expression) function application) (variable) (general constructor) (parenthesized expression) (tuple, k>=2) (list, k>=1) (arithmetic sequence) - 18 - Beispiel zur Grammatik quadratsumme x y = (quadrat x) + (quadrat y) Zeichenfolge im Programm quadratsumme x y = (quadrat x) + (quadrat y) + quadrat x Grundlagen der Programmierung 2 (1.A) Name in der Grammatik (sog. Nichtterminal) hFunktionsnamei hParameteri hParameteri = gleiches Zeichen wie in Grammatik hAusdrucki der Form hAusdrucki + hAusdrucki binärer Infix-Operator Anwendung: quadrat ist ein Ausdruck und x ist ein Ausdruck - 19 - Programm Ein Haskell-Programm ist definiert als • Eine Menge von Funktionsdefinitionen • Eine davon ist die Definition der Konstanten main. Ohne main: dann ist es ein Modul Grundlagen der Programmierung 2 (1.A) - 20 - Haskell: Verschiedenes . . . Prelude: vordefinierte Funktionen, Typen und Datenkonstruktoren Präfix, Infix, Prioritäten: ist möglich für Operatoren Konventionen zur Klammerung: s1 s2 . . . sn ≡ ((. . . (s1 s2) s3 . . .) sn) Funktionsdefinitionen: • formale Parameter müssen verschiedenen sein; • keine undefinierten Variablen im Rumpf! Weitere Trennzeichen: “{“,“}“ Semikolon “; “ Layout-sensibel: bewirkt Klammerung mit {, }. Grundlagen der Programmierung 2 (1.A) - 21 - Fallunterscheidung: IF-THEN-ELSE Syntax: if hAusdrucki then hAusdrucki else hAusdrucki if“, then“, else“ sind reservierte Schlüsselworte ” ” ” Der erste Ausdruck ist eine Bedingung (Typ Bool) Typisierung: if Bool . . . then typ else typ (if 1 then 1 else 2) ergibt einen (Typ-)Fehler Grundlagen der Programmierung 2 (1.A) - 22 - Bedingungen, Arithmetische Vergleiche Die Infixoperatoren ==, <, >, <=, >=, / = haben den Typ: Integer -> Integer -> Bool Achtung: = ist reserviert für Funktionsdefinitionen und let Boolesche Ausdrücke sind kombinierbar mit not, ||, && Konstanten sind True, False. (nicht, oder, und) Beispiel: 3.0 <= x && x < 5.0 Grundlagen der Programmierung 2 (1.A) - 23 - Darstellungen eines Programms sichtbare Syntax: vom Programmierer benutzt Interne Syntax: “Linearisierung“; entzuckerte Version; voll geklammert; alle Operatoren sind Präfix; kein Layout Ableitungsbaum (Herleitungsbaum): Interne Darstellung; Vom Kompiler erzeugt Grundlagen der Programmierung 2 (1.A) - 24 - Darstellungen eines Programms Syntaxbaum: Eindeutige Darstellung des Programms als markierter Baum. Wird vom Compiler/Interpreter (Parser) intern erzeugt. Ermöglicht die eindeutige Definition der Ausführung des Programms. Entspricht der hierarchischen Schachtelung des Programms. Z.B. Klammerstruktur. Grundlagen der Programmierung 2 (1.A) - 25 - Syntaxbaum: Beispiele if x <= 0 then 1 else x*(quadrat (x-1)) ifThenElseUUUUU <=DD x {{ {{ { { {{ }{ { i iiii iiii i i i i it iii DD DD DD DD ! 0 1 UUUU UUUU UUUU U* x ∗ KKKK KK KK KK KK KK % quadrat x x*(quadrat (x-1)) qq qqq q q qqq q x qq x − MMMM MMM MMM MMM & 1 ∗ MMMMM MMM MMM MMM & quadrat x Grundlagen der Programmierung 2 (1.A) q qqq q q q qqq q q q x − MMMM MMM MMM MMM & 1 - 26 - Syntaxbaum: Beispiele Zwei Syntaxbäume zu 1 − @@ @@ @@ @@ 2 }} }} } } } ~} ~ ~~ ~~ ~ ~~ ~ 1 (1 − (2 − 3)) − ?? ?? ?? ?? 3 − ?? ?? ?? ?? − AA 1-2-3: AA AA AA 3 ((1 − 2) − 3) 2 Nur einer ist ist gültig in Haskell. Grundlagen der Programmierung 2 (1.A) - 27 -