Konzepte von Programmiersprachen WS 03/04

Werbung
Konzepte von Programmiersprachen WS 03/04
http://www-pu.informatik.uni-tuebingen.de/users/klaeren/kvps
H. Klaeren,
H. Gast
B LATT 13
Abgabe: 5.2.2004, 9:30h
(Seite 1 / 2)
Hinweise: • Dies ist das letzte Blatt der Vorlesung.
• Schriftliche Abgaben können als paper.ps oder paper.pdf den elektronischen beigelegt werden.
• Es kann für dieses Blatt nur ein Testat abgelegt werden.
• Seminarankündigung: Code-Reuse und Polymorphie (siehe Rückseite)
Aufgabe 1 [8] Geheimnisprinzip in OCaml-Modulen†
Das Geheimnisprinzip für Module besagt, daß bei der Benutzung eines Moduls dessen interne Realisierung unwichtig sein soll: Allein die Schnittstelle des Moduls bestimmt die exportierte Funktionalität und die erlaubten Zugriffe durch andere Module. Das OCaml-Modulsystem1 bietet zwei Mechanismen an: Zum einen können type-Definitionen abstrakt gelassen werden, indem man den Implementierungstyp nicht angibt. Damit kann der Benutzer des Moduls keine primitiven Operationen auf
Daten dieses Typs ausführen. Zum anderen werden nur solche Funktionen exportiert, die explizit in
der Schnittstelle erwähnt sind. Das Modulsystem unterscheidet genau zwischen Modulen (struct)
und Schnittstellen (sig für signature). Mit module . . . = und module type . . . = kann man
Modulen und Signaturen Namen zuweisen. Der Ausdruck (M:S) bezeichnet eine Einschränkung
der aus M exportieren Bezeichner auf die Signature S (siehe auch Dokumentation).
Löse in einer Datei mod.ml folgende Aufgaben; wenn nicht lauffähiger/nicht compilierbarer Code
vorkommt, dann sollen die entsprechenden Teile in Kommentaren angegeben werden.
1. Schreibe ein Modul Vector, das einen Typ vector als int array definiert, bei dem die untere und obere Grenze im 0ten und 1ten Eintrag gespeichert ist. Weiterhin sollen Funktionen
make l u, set v i x, get v i definiert werden. make legt einen neuen Vector mit Schranken l, u
an und gibt zu Dokumentationszwecken auch den String "Vector" aus. set und get greifen
auf das i te Element von v zu, wobei l ≤ i ≤ u als Bounds-check überprüft wird. Benutze eine
Hilfsfunktion index v i, die den Bounds-check durchführt (evtl. exception Out_of_bounds)
und den Index des i ten Elements im Array v zurückliefert.
2. Wähle OPENVEC so, daß der Implementierungstyp von vector sichtbar bleibt, aber die Hilfsfunktion verborgen wird. Zeige, daß OPENVEC unsicher ist, indem Du ein Modul M1 aus Vector
mit Signatur OPENVEC definierst und dann mit make einen vector erzeugst. Überschreibe
dessen gespeicherte Grenzen überschreibst und führe einen unzulässigen set-Aufruf durch,
der nicht zu einer Out_of_bounds Exception führt, sondern erst beim Zugriff auf das Array
selbst fehlschlägt (Invalid_argument).
3. Gehe wieder vom Modul Vector aus, schreibe aber eine Signatur CLOSEVEC, die die Implementierung von vector verbirgt. Definiere mit dieser Signatur eine Modul M2 und zeige (durch
Compilerfehlermeldung), daß die vorherige Zerstörung nicht mehr möglich ist.
4. Schreibe ein Modul Better, das vector, make, get, set wie vorher definiert, als Implementierungstyp aber einen Record verwendet und darin obere und untere Schranke sowie ein
int array für die eigentlichen Daten ablegt. Seine make Funktion gibt den String "Better"
aus.
5. Versuche die Module M3 und M4 mit den Signaturen OPENVEC und CLOSEVEC für Better zu
definieren. Welches funktioniert und warum/warum nicht? Erkläre die Fehlermeldung!
1 Eine ausführliche Dokumentation zu Modulen findet sich bei http://caml.inria.fr/ocaml/htmlman/manual004.html
und Abschnitt 8 der Einführung in OCaml vom Semesteranfang.
Konzepte von Programmiersprachen WS 03/04
http://www-pu.informatik.uni-tuebingen.de/users/klaeren/kvps
H. Klaeren,
H. Gast
B LATT 13
Abgabe: 5.2.2004, 9:30h
(Seite 2 / 2)
6. Schreibe ein parametrisiertes Modul Withvector(Vec:CLOSEVEC), das in seiner einzigen Funktion main() die make-Funktion des Parameters Vec aufruft. Instanziiere nun das Modul als
Withvector(Vector) und Withvector(Better) und rufe jeweils die Funktionen alle einmal
auf.
7. (schriftlich) Erkläre in 1-2 Sätzen, warum das Modul Withvector mit beiden Modulen funktioniert! Sind damit die Module Vector und Better in jedem Fall austauschbar (warum?) Was
wäre passiert, wenn Withvector ein OPENVEC-Argument eingefordert hätte?
Aufgabe 2 [8] Entwurfsentscheidungen bei Ausnahmen†
Finde heraus, wie das OCaml-Exception-System2 die 8 Designfragen nach Sebesta (siehe Vorlesung)
beantwortet. Schreibe jeweils eine kurze Erklärung und ein Programmstück, das Deine Aussage
belegt (d.h.: Das Programm verhält sich so, wie es Deine Erklärung vermuten läßt). Das Programm
muß nichts sinnvolles tuen, es reicht völlig aus, die entsprechenden Funktionsaufrufe zu veranlassen
und an geeigneter Stelle eine Exception zu werfen bzw. zu fangen.
Aufgabe 3 [4] Ausnahmen in funktionalen und imperativen Sprachen
In Pascal-artigen Sprachen (mit Laufzeitstapel) müssen die Aktivierungsblöcke bei einer Exception
einzeln und sorgfältig vom Stapel entfernt werden. Bei funktionalen Sprachen hingegen können
einfach ganze Teile des Stapels verworfen werden. Dazu wird ein separater Stapel von ExceptionHandlern mitgeführt, in denen jeweils der Zustand von Variablenumgebung, Codezeiger und Aufrufstapel festgehalten wird, wie sie bei Aktivierung des Handlers vorlagen. Erkläre den Zusammenhang
mit den Stichpunkten Garbage Collection, Haldenbasierte Allokation und Globales Display.
Aufgabe 4 [4 (opt)] Ausnahmen und Continuations
Erkläre grob, wie man first-class continuations, z.B. in Scheme, für die Implementierung von ExceptionSystemen verwenden kann. Gib Definitionen für try/catch Konstrukte (Handler) und raise an.
Seminar: Code-Reuse und Polymorphie – Zwischen Softwaretechnik und Programmiersprachen
Ein grundsätzliches Ziel der Softwaretechnik ist es, einmal geschriebenen Code möglichst oft wieder
zu verwenden – so lassen sich die Kosten und Entwicklungszeit für neue Programme dämpfen und
die Entwicklung von gutem, teurerem Code rechtfertigen.
Um dieses Ziel zu erreichen braucht man Unterstützung durch die verwendete Programmiersprache.
Ein wesentliches Phänomen ist dabei die Polymorphie, heute besonders bekannt in Form von Vererbung
in objekt-orientierten Sprachen: Ein Objekt kann in verschiedenen Kontexten eingesetzt werden,
solange es die ”Rolle” der jeweils geforderten Oberklasse erfüllt.
Diese Fähigkeit, ein einmal definiertes Sprachobjekt immer neu zu verwenden und an den Kontext
anzupassen, wird nicht nur von diesem, sondern vielen anderen Sprachkonstrukten unterschiedlicher
Herkunft realisiert. Im Seminar werden diese Konstrukte untersucht und verglichen; dabei sollen
anhand von Beispielen die relativen Stärken und Schwächen herausgearbeitet werden.
Beispielsprachen: Java, Generic Java, C++, Ada, ML, Haskell
Erste Besprechung: Siehe kommentiertes Vorlesungsverzeichnis (ab Mitte Februar).
2 Dokumentation:
/afs/wsi/i386 fbsd46/ocaml-3.06/html/manual003.html
http://caml.inria.fr/ocaml/htmlman/manual003.html
Herunterladen