Grundlagen der Programmierung 2 (1.A) Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 20. April 2006 Grundlagen der Programmierung 2: Geplanter Inhalt der ersten Hälfte • • • • • • • Programmiersprachen: Paradigmen rekursives Programmieren in Haskell Ströme als unendliche Listen in Haskell Operationale Semantik: Haskell Sortieren, Suchen und Bäume Polymorphe Typen und Typklassen Parallele Berechnungen Grundlagen der Programmierung 2 (1.A) - 2 - Bücher, Literatur, URLs • • • • http://www.cs.uni-frankfurt.de/˜prg2 www.haskell.org Haskell-Website Manuel Chakravarty und Gabriele Keller Einführung in die Programmierung mit Haskell Richard Bird: Introduction to Functional Programming Using Haskell Grundlagen der Programmierung 2 (1.A) - 3 - Interpreter / Compiler Interpreter Compiler (Übersetzer) Ablaufumgebung Grundlagen der Programmierung 2 (1.A) führt ein Programm aus, (bzw. wertet ein Programm aus), Grundlage: Text des Programms Jeder Programmbefehl wird einzeln eingelesen und dann ausgeführt. erzeugt aus Programm einen ausführbaren Modul. Programmumstellungen, Optimierungen Effekt des Programms muss gleich bleiben. Hier erfolgt die Ausführung des Programms - 4 - Laufzeit / Compilezeit Compilezeit: Zeitraum der Analyse bzw. Übersetzung des Programms statische Typüberprüfung, Optimierung. Laufzeit: Zeitraum der Ausführung des Programms Z.B. dynamische Typüberprüfung, Ein-Ausgabe. Grundlagen der Programmierung 2 (1.A) - 5 - Programmiersprachen: wesentliche Merkmale Syntax Beschreibung der Programme als Texte Semantik Beschreibung der Aktionen / Bedeutung eines Programms Grundlagen der Programmierung 2 (1.A) - 6 - Programmiersprachen: wesentliche Merkmale imperativ Programm ist Folge von Befehlen sukzessive Änderung des Speicherinhalts Ergebnis: letzter Zustand Ein imperatives Programm sagt präzise: was (welche Anweisung), wann (Reihenfolge der Anweisungen) womit (Speicherplatz/Variable) zu geschehen hat. prozedural: Strukturierung in (imperativen) Programmiersprachen Prozedur = Unterprogramm Aufruf mit Argumenten im Programm Ziel: Übersichtlichkeit; Wiederverwendbarkeit Grundlagen der Programmierung 2 (1.A) - 7 - Programmiersprachen: Merkmale (2) funktional: Programm ist strukturiert in Funktionsdefinitionen Ausdrücke = Anwendung von Funktionen auf Argumente Berechnung = Auswertung von Ausdrücken Ergebnis = Nur der Return-Wert Varianten von funktionalen Programmiersprachen: nicht-strikt: Argumente werden so spät wie möglich ausgewertet strikt: Argumente werden vor Funktionsaufruf ausgewertet pur: Objekte haben nur einen Wert, keine Mutation möglich nicht-pur: Objekte veränderbar, Seiteneffekte möglich deklarativ: Idealfall: Spezifikation = deklaratives Programm Betonung auf Logik, weniger algorithmisch Beispiele: logische Programmierung, Prolog Grundlagen der Programmierung 2 (1.A) - 8 - Programmiersprachen: Merkmale (3) objektorientiert: Verwendung in imperativen Programmiersprachen Strukturierung des Programm in Klassen. Ziel: Übersichtlichkeit, Wiederverwendung Ausführung eines Programms: Erzeugung von Objekten Austausch von Nachrichten zwischen Objekten Grundlagen der Programmierung 2 (1.A) - 9 - Programmiersprachen: Merkmale (4) typisiert Alle Programmiersprachen haben eine Typisierung Programmtext • statische Typisierung: • dynamische Typisierung: Ausführungszeit des Programms • • schwache Typisierung: Typfehler zur Laufzeit sind möglich starke Typisierung: Typfehler zur Laufzeit sind nicht möglich Grundlagen der Programmierung 2 (1.A) - 10 - Beispiele für Programmiersprachen Haskell: Eine funktionale Programmiersprache funktional, nicht-strikt, hat ein polymorphes und starkes Typsystem, flexible Datenstrukturen, gute Abstraktionseigenschaften, Ziele: pures Programmieren, Auswerten von Ausdrücken rekursives Programmieren, Typsystem Python: Eine prozedurale Programmiersprache prozedural; schwaches, dynamisches Typsystem, flexible Datenstrukturen, Objektorientierung. Grundlagen der Programmierung 2 (1.A) - 11 - Java zentrale Idee der Objektorientierten Programmiersprachen (OOP) : Objekt als Strukturierungskonzept. Objekte zusammengesetzte (Daten-)Einheit belegt Speicherplatz haben eine Identität. sind gekapselt. Veränderungen von Objekten werden stets mittels der definierten Methoden durchgeführt. gehören zu einer Klasse – (Instanz einer Klasse) Kommunikation durch Senden/Empfangen von Nachrichten. Grundlagen der Programmierung 2 (1.A) - 12 - Fahrzeugbeispiel: (1) class Fahrzeug { public double Hoechstgeschwindigkeit; private String Eigentuemer; private static long Anzahl; static { Anzahl = 0; } public static long Anzahl() { return Anzahl; } public Fahrzeug() { Anzahl = Anzahl + 1; } Grundlagen der Programmierung 2 (1.A) // Konstruktor: - 13 - Java: Fahrzeugbeispiel public Fahrzeug(double Hoechstgeschwindigkeit, String Eigentuemer) { Anzahl = Anzahl +1; this.Eigentuemer = Eigentuemer; this.Hoechstgeschwindigkeit = Hoechstgeschwindigkeit; } public double Hoechstgeschwindigkeit () { return Hoechstgeschwindigkeit ; } public void loesche_Fahrzeug() { Anzahl = Anzahl - 1; } public String Eigentuemer () { return Eigentuemer; } } Grundlagen der Programmierung 2 (1.A) - 14 - Java: Fahrzeugbeispiel Grundlagen der Programmierung 2 (1.A) - 15 - Java: Fahrzeugbeispiel class Auto extends Fahrzeug { public String Autokennzeichen; public Auto(double Hoechstgeschwindigkeit, String Eigentuemer, String kennzeichen) { super(Hoechstgeschwindigkeit, Eigentuemer); this.Hoechstgeschwindigkeit = Hoechstgeschwindigkeit; this.Autokennzeichen = kennzeichen; } } Grundlagen der Programmierung 2 (1.A) - 16 - OO: Klassen Klassen entsprechen Typschablonen • werden in der OO-Programmiersprache definiert. • enthalten die Definition der Struktur der zugehörigen Objekte und der Methoden, die auf Objekte dieser Klasse anwendbar sind. • entsprechen einer Menge von Objekten mit gleichem Verhalten. • i.a. eine Realisierung eines abstrakten Datentyps • entsprechen einem Typ zur Compilezeit • sind in einer (Baum-)Hierarchie angeordnet (Ober- ; Unterklasse) • Die Klassenhierarchie wird verwendet, um allgemeine Aspekte von Objekten in einer Oberklasse zu definieren und zu implementieren, und dann in Unterklassen die spezielleren Eigenschaften zu implementieren. • • • Elementare Datentypen (Zahlen, . . . ) sind keine Objekte können zu Objekten gemacht werden, falls nötig Vereinfachte Handhabung in Java 5 Grundlagen der Programmierung 2 (1.A) - 17 - Vergleich mit Haskell Java Klasse Methode Objekt Senden von Nachrichten Seiteneffekte Aliasing Grundlagen der Programmierung 2 (1.A) | entspricht entspricht entspricht entspricht | | Haskell Typ bzw. einer Typklasse Funktion (bzw. Prozedur) konstruiertem Datenobjekt. Funktionsaufruf Nur Kopieren möglich unproblematisch: keine Seiteneffekte - 18 - Objekte und Methoden: Genauer Objekt besteht aus Daten; bzw. Attributen das Innere eines Objektes ist nicht direkt sichtbar. Attribute sind nur über erlaubte Methodenaufrufe änderbar das Innere des Objektes (seine Attribute) sichtbar und änderbar. gehören zu einer Klasse: ( Instanz einer Klasse) Objekt analog zu einem Record, bei dem die einzelnen Attribute mit Attributnamen ansprechbar sind. Satz (Verbund) in einer Datenbank, bestehend aus Attributen. n-Tupel in Haskell mit Attributnamen Grundlagen der Programmierung 2 (1.A) - 19 - Methoden Methoden: auf Objekten ausführbare Operationen, analog zu Prozeduren. Methodenaufruf: Senden einer Nachricht Methode kann per Dot-Notation an ein Objekt gekoppelt sein bzw. wird auf ein Objekt angewendet. Nachrichten: Argumente der Prozedur. Grundlagen der Programmierung 2 (1.A) - 20 - Spezifische Aufgaben von Methoden: Konstruktion: Erzeugen und Initialisieren eines Objekts Destruktion: Abschlussarbeiten und Löschen eines Objekts Selektion: Lesen von internen Daten des Objekts Modifikation: Ändern der internen Daten des Objekts Andere Verarbeitung allgemeine Prozedur Grundlagen der Programmierung 2 (1.A) - 21 - Logische Programmierung Grundlegende Idee: Verwendung der Prädikatenlogik Genauer: Hornlogik Programm besteht nur aus Formeln ∀x1, . . . xn.A1 ∧ . . . ∧ An ⇒ B (Hornklauseln) Schreibweise: B : −A1, . . . An Grundlagen der Programmierung 2 (1.A) - 22 - Logische ausführung Programmierung: Programm- Ausführung = Beantwortung von Anfragen an das Programm Anfrage ist eine Formel: ∃y1, . . . ym.C1 ∧ . . . ∧ Cm entspricht einer negativen Hornklausel Antwort die möglichen Tupel y1, . . . ym bzw Ja / Nein Ausführung: Schlussfolgern Grundlagen der Programmierung 2 (1.A) - 23 - Logische Programmierung: Beispiel vater(peter,maria). mutter(susanne,maria). vater(peter,monika). frau(maria). frau(susanne). frau(monika). mann(peter). eltern(X,Y) :- vater(X,Y). eltern(X,Y) :- mutter(X,Y). Anfrage: Antwort: eltern(peter,maria)? Ja Anfrage: Antwort 1: Antwort 2: eltern(peter,X)? X = maria X = monika Grundlagen der Programmierung 2 (1.A) - 24 - Haskell rekursive Programmierung mit der streng typisierten, funktionalen Programmiersprache Haskell Grundlagen der Programmierung 2 (1.A) - 25 - 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. 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 Funktionen sind Datenobjekte mögliche Verwendung: in Datenobjekten, als Argument, als Resultat. Grundlagen der Programmierung 2 (1.A) - 26 - Programmierung in Haskell Interpreter Hugs 98 und GHCi Grundprinzipien: • • • Definition von Funktionen quadrat x = x*x Aufbau von Ausdrücken: Anwendung der Funktion auf Argumente, die wieder Ausdrücke sein können. 3*(quadrat 5) Nur der Wert von Ausdrücken wird bei der Auswertung zurückgegeben. 75 Grundlagen der Programmierung 2 (1.A) - 27 - Umgang mit dem Interpreter Aufruf: Online-Report >:h >:t Ausdruck >:set +t ... ghci (im richtigen Fenster) http://www.haskell.org/onlinereport Hilfe druckt den Typ des Ausdrucks Optionen ändern Module im Interpreter verwenden: :m +Char +Numeric ... Grundlagen der Programmierung 2 (1.A) - 28 - Einfache Daten und Operatoren • ganze Zahlen • • • • • beliebig lange ganze Zahlen rationale Zahlen Gleitkommazahlen Zeichen Datenkonstruktoren • • • Arithmetische Operatoren: Arithmetische Vergleiche: Logische Operatoren: Grundlagen der Programmierung 2 (1.A) Typ Int mit |n| ≤ 231 − 1 = 2147483647 (vom Typ Integer), 3%7 (Rational) 3.456e+10 (Float) ’a’ Char True, False; Typ Bool +, −, ∗, /, ==, <=, < . . . &&, ||, not - 29 - Beispiel Definition eines Polynoms x2 + y 2: quadratsumme x y = quadrat x + quadrat y Auswertung: ... Main> quadratsumme 3 4 25 Grundlagen der Programmierung 2 (1.A) - 30 - Typen in Haskell Typ Int Integer Float Double Integer -> Integer -> Integer -> Integer -> Integer Integer -> Grundlagen der Programmierung 2 (1.A) Integer Integer Konstanten, Funktionen 1,2,3,4,. . . 1,2,3,4,. . . 1.23e45 1.23e45 (+) quadrat quadratsumme - 31 - Typen in Haskell Beispiel Die Ausgabe des Interpreters für die Addition (+) ist komplizierter: (+) :: forall a. (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) - 32 - (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: Grundlagen der Programmierung 2 (1.A) formale Parameter. Stelligkeit der Funktion: (ar(f )) - 33 - Beispiel zur Grammatik quadratsumme x y = (quadrat x) + (quadrat y) quadratsumme x,y = (quadrat x) + (quadrat y) + quadrat x Grundlagen der Programmierung 2 (1.A) Funktionsname formale Parameter gleiches Zeichen wie in Grammatik hAusdrucki der Form hAusdrucki + hAusdrucki binärer Infix-Operator Anwendung: quadrat ist ein Ausdruck und x ist ein Ausdruck - 34 - 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) Kontextbedingungen in 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) - 35 - Fallunterscheidung Syntax: if hAusdrucki then hAusdrucki else hAusdrucki if“, then“, else“ sind reservierte (Schlüsselworte) ” ” ” und dürfen nicht als Funktionsnamen bzw. Parameternamen verwendet werden. Der erste Ausdruck ist eine Bedingung. Diese muss Typ Bool haben. Typisierung: if Bool . . . then typ else typ (if 1 then 1 else 2) ergibt einen Fehler Grundlagen der Programmierung 2 (1.A) - 36 - 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, ||, && (nicht, oder, und) Konstanten sind True, False. Eine kompliziertere Bedingung: 3.0 <= x && x < 5.0 Grundlagen der Programmierung 2 (1.A) - 37 - Darstellungen eines Programms Benutzer-Syntax: vom Programmierer benutzt Interne Syntax: “Linearisierung“; entzuckerte Version; voll geklammert; alle Operatoren sind Präfix; kein Layout Ableitungsbaum (Herleitungsbaum): Vom Kompiler erzeugt Syntaxbaum: Eindeutige Darstellung des Programms in einem markierten Baum. Hierauf lässt sich eindeutig die Ausführung des Programms definieren. Grundlagen der Programmierung 2 (1.A) - 38 - Syntaxbaum: Beispiele if x <= 0 then 1 else x*(quadrat (x-1)) ifThenElseXXXXXXX <=FF x y yy yy y y |y y ii iiii i i i iii iiii it iii FF FF FF F" 0 1 XXXXXX XXXXXX XXXXXX XXXXXX X, o o o oo o o oo ooo o o woo ∗ x pp ppp p p p pw pp quadrat x Grundlagen der Programmierung 2 (1.A) app p ppp p p pp ppp p p pw p − 1 - 39 - Syntaxbaum: Beispiele Zwei Syntaxbäume zu 1*2: ∗ >>> 1 >> >> > appFF tt tt tt t ty t appJJ 2 ∗ Grundlagen der Programmierung 2 (1.A) FF FF FF F" yy yy y yy y| y JJJ JJJ JJJ % 2 1 - 40 - Aufrufhierarchie und Rekursive Definitionen f, g, fi seien Haskell-definierte Funktionen. f referenziert g direkt, f referenziert g (indirekt), f ist direkt rekursiv, f ist rekursiv, Verschränkte Rekursion: Grundlagen der Programmierung 2 (1.A) wenn g im Rumpf von f vorkommt. wenn es Funktionen f1, . . . , fn gibt, so dass gilt: f referenziert direkt f1, f1 referenziert direkt f2, . . . , fn referenziert direkt g. wenn f sich selbst direkt referenziert. wenn f sich selbst (indirekt) referenziert. wenn f die Funktion g referenziert und g die Funktion f auch für allgemeinere Fälle - 41 - Beispiel: Aufrufhierarchie quadrat x = x*x quadratsumme x y = (quadrat x) + (quadrat y) quadratsumme ruft direkt die Funktion quadrat auf, quadratsumme ruft direkt die (eingebaute) Funktion ∗ auf Die Funktion quadratsumme ist somit nicht rekursiv Grundlagen der Programmierung 2 (1.A) - 42 -