Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage:

Ähnliche Präsentationen


Präsentation zum Thema: "Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage:"—  Präsentation transkript:

1 Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage:

2 Programmierung 1 - Repetitorium Montag, den Kapitel 9 Typabstraktion und Modularisierung

3 Programmierung 1 - Repetitorium 9.1 Module Beim modularen Design zerlegt man ein Programm in eine kleine Zahl von Modulen. SML stellt drei Standard-Konstruktoren zur Verfügung : Strukturen, Signaturen und Funktoren Ein Modul implementiert eine Schnittstelle, welche die Typen und Funktionsweise der von dem Modul bereitgestellten Prozeduren angibt. Das Abstraktionsprinzip besagt, dass zur Benutzung eines Moduls nur Kenntnisse seiner Schnittstellen erforderlich sind und keine Kenntnis über deren Implementierung. Beim modularen Design lässt sich die Implementierung einer Schnittstelle verbessern ohne die Funktionalität zu ändern.

4 Programmierung 1 - Repetitorium 9.2 Strukturen Eine Struktur ist eine Kollektion von Objekten, die durch Bezeichner identifiziert werden und als Felder der Struktur bezeichnet werden. (z.B. Math) Auf die Felder einer Struktur kann mithilfe von zusammengesetzten Bezeichnern zugegriffen werden. (z.B. Math.pi) Strukturen können mithilfe von Strukturdeklarationen eingeführt werden. structure s = struct Deklarationen end structure S = struct val a = 4 exception E datatype t = A | B structure T = struct val a = a + 3 end Bezeichner S wird an eine Struktur mit den Feldern a, E, t und T gebunden. S.a ist eine Konstante S.E ist eine Ausnahme S.t ist ein Konstruktortyp S.A und S.B sind Konstruktoren S.T ist eine Struktur

5 Programmierung 1 - Repetitorium 9.2 Strukturen Für Strukturen wählt man Bezeichner, die mit Großbuchstaben beginnen. Strukturdeklarationen sind nicht innerhalb von Let-Ausdrücken erlaubt. Da Strukturen keine Werte sind, können sie nicht als Argument oder Ergebnis einer Prozedur verwendet werden. Mithilfe der Deklaration open s kann man die lokale Bindung der Felder einer Struktur auf der Ebene der open-Deklaration sichtbar machen. val a = S.A exception E = S.E datatype t = datatype S.t structure T = S.T Die Synonym-Deklarationen open s hat denselben Effekt wie exception E = S.E datatype t = datatype S.t erzeugen keine neue Ausnahme bzw. keinen neuen Datentyp.

6 Programmierung 1 - Repetitorium 9.3 Typabstraktion Mithilfe von Signaturen kann man abstrakte Typen zusammen mit ihren Operationen einführen. signature ISET = sig type set val empty : set val insert : int * set -> set val member : int * set -> bool end type set führt einen abstrakten Typ ohne Gleichheit ein. eqtype set führt einen abstrakten Typ mit Gleichheit ein. Für Signaturen wählt man üblicherweise Bezeichner, die nur aus Großbuchstaben bestehen. Wir können eine Struktur ISet deklarieren, die die Signatur ISET implementiert, also den Signaturconstraint ISet :> ISET erfüllt, womit die Implementierung von ISet verborgen wird.

7 Programmierung 1 - Repetitorium 9.3 Typabstraktion structure ISet :> ISET = struct type set = int list val empty = nil val insert = op:: fun member (x,s) = List.exists (fn y => y=x) s end Signaturen beschreiben die Schnittstelle einer Typabstraktion. Eine Typabstraktion besteht aus einem abstrakten Typ, Konstanten und einigen Operationen. Typabstraktionen entkoppeln die Benutzung einer Funktionalität von ihrer Implementierung und ermöglichen so ein einfacheres Debugging und Verbessern von Implementierung, da nur die Schnittstelle und nicht deren Implementierung nach außen sichtbar ist.

8 Programmierung 1 - Repetitorium 9.3 Typabstraktion Eine Einführung von abstrakten Typen mithilfe eines Signaturconstraints ist generativ. Darstellungsgleichheit : [ 2, 1 ] = ISet.insert ( 2, ISet.insert ( 1, ISet.empty ) ) [ 1, 2 ] = ISet.insert ( 1, ISet.insert ( 2, ISet.empty ) ) structure S :> ISET = ISet Aufgrund der Generativität sind die Typen ISet.set und S.set verschieden und können somit nicht kombiniert verwendet werden. Abstrakte Gleichheit : { 2, 1 } = { 1, 2 } Dieses Problem lässt sich beheben durch die Erweiterung von ISET um val eq : set * set -> bool und von ISet um fun subset (s,s) = List.all (fn x => member (x,s)) s fun eq (s,s) = subset (s,s) andalso subset (s,s)

9 Programmierung 1 - Repetitorium 9.4 Schlangen Bei Schlangen handelt es sich um Listen, die nur mit den angegebenen Operationen konstruiert und zerlegt werden dürfen. Vorteile der Verwendung der Typabstraktion : Lesbarkeit, Typdisziplin, Laufzeit Neue Elemente werden am Ende der Schlange eingefügt. Eigenschaft : FIRST IN – FIRST OUT (FIFO) signature QUEUE = sig type a queue val empty : a queue val insert : a * a queue -> a queue val head : a queue -> a (* EMPTY *) val tail : a queue -> a queue (* EMPTY *) end

10 Programmierung 1 - Repetitorium 9.4 Schlangen structure Queue :> QUEUE = struct type a queue = a list val empty = nil fun insert (a,q) = [a] val head = hd val tail = tl end Eine effizientere Implementierung von Schlangen : structure FQueue :> QUEUE = struct type a queue = a list * a list val empty = ([],[]) fun insert (a,([],_)) = ([a],[]) | insert (a,(q,r)) = (q,a::r) fun head (q,r) = hd q fun tail ([x],r) = (rev r,[]) | tail (q,r) = (tl q,r) end

11 Programmierung 1 - Repetitorium 9.4 Schlangen Die effiziente Implementierung der Typabstraktion QUEUE stellt eine Schlange durch ein Paar (q,r) von zwei Listen dar, wobei die Liste die eigentliche Schlange repräsentiert. Darstellungsinvariante : Nichtleere Schlangen werden durch ein Paar realisiert, dessen erste Liste nichtleer ist. Leere Schlangen werden also durch ( [ ], [ ] ) dargestellt. Die Laufzeit der Operation tail liegt in O(n). Insert und head haben Laufzeit O(1).

12 Programmierung 1 - Repetitorium 9.5 Funktoren functor Set (type elem val compare : elem * elem -> order) :> sig type set val empty : set val insert : elem * set -> set val member : elem * set -> bool end = struct type set = elem list val empty = nil val insert = op:: fun member(x,s) = List.exists (fn y => compare(x,y)=EQUAL) s end

13 Programmierung 1 - Repetitorium 9.5 Funktoren Eine polymorphe Realisierung von Signatur und Struktur ist mit Funktoren möglich. Beim Beispiel der Schlange benötigen wir hierfür einen Elementtyp und eine Vergleichsprozedur, welche die Ordnung zur Verfügung stellt. Verwendung des Funktors Set für Mengen : structure ISet :> ISET = Set (type elem = int, val compare = Int.compare) structure StringSet = Set (type elem = string, val compare = String.compare)

14 Programmierung 1 - Repetitorium 9.6 Programmiersprachliche Details Neue Arten von programmiersprachlichen Objekten : Moduldeklarationen von Strukturen, Signaturen und Funktoren Die Namensräume für die verschiedenen Arten sind syntaktisch getrennt. Eine Strukturdeklaration structure S :> Sig = Rumpf bindet den Bezeichner S statisch an die Signatur Sig. Außerdem wird statisch überprüft, dass die durch Rumpf beschriebene Struktur die Signatur Sig erfüllt. Dafür gelten die folgenden Regeln : 1.Die durch Rumpf beschriebene Struktur muss mindestens die Felder der Signatur Sig realisieren. 2.Die durch Rumpf beschriebene Struktur muss die Felder der Signatur Sig mindestens so allgemein realisieren wie diese in Sig spezifiziert ist. 3.Signatur-constraints sind auch dann zulässig, wenn die Signatur keine abstrakte Typen spezifiziert. Logisch verwandte Konzepte : Strukturen (Werte), Funktoren (Prozeduren), Signaturen (Typen)

15 Programmierung 1 - Repetitorium 9.7 Komponenten Große Programme zerlegt man in Komponenten, die getrennt auf Dateien geschrieben werden. Eine Komponente besteht aus einer Signatur und einer Implementierung. Die Implementierung deklariert eine Struktur, die die Signatur realisiert. Signatur und Implementierung werden auf getrennte Dateien geschrieben und müssen vor Benutzung übersetzt werden, wobei die Signatur zuerst übersetzt werden muss. Übersetzungsbefehle : mosmlc -c A.sig (Signatur) mosmlc -c A.sml (Implementierung) mosmlc -toplevel A.sml (Funktoren) Abhängigkeiten von Komponenten werden im Abhängigkeitsgraphen mit einer Hauptkomponente dargestellt und sind Bestandteil der Programm-Architektur. Das direkt ausführbare Programm erhält man durch Übersetzung der Hauptkomponente. Der Linker bindet dann die einzelnen Komponenten zusammen. mosmlc H.sml (Hauptkomponente)


Herunterladen ppt "Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage:"

Ähnliche Präsentationen


Google-Anzeigen