Programmierparadigmen

Werbung
Programmierparadigmen
Wintersemester 2011/12
Torsten Görg
7. Übung
8./9./10. Februar 2012
Organisatorische Hinweise
Damit wir besser einschätzen können, wie aufwändig die Bearbeitung der Übungsaufgaben für Sie ist, und wieviel
Zeit Sie dafür benötigen, möchten wir Sie bitten, in Ihrer Abgabe zu jeder Aufgabe die Zeit mit anzugeben, die
Sie zur Bearbeitung dieser Aufgabe benötigt haben (inklusive Recherchen und Besprechungen im Abgabe-Team).
Diese Zusatzangabe ist freiwillig und dient nur zur Verbesserung zukünftiger Aufgabengestaltungen.
Aufgabe 7.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Punkte
In der Vorlesung wurde aufgezeigt, dass durch Wartungsänderungen an objektorientierten Programmen
überraschende Probleme auftreten können. Dies soll nun an einem einfachen, in Java implementierten
Beispielsystem betrachtet werden, das Sie in seiner Ausgangsform in der Datei Aufgabe_7_1.zip auf der
Veranstaltungs-Homepage finden. Zu dem System gehören eine externe Bibliothek, die aus den beiden
Klassen LibClassA und LibClassB besteht, und die eigentliche Applikation, die in der Klasse OwnClass
realisiert ist.
1. Welche Ausgaben liefert dieses Beispielsystem?
2. Bei einem Bibliotheks-Update wird die Klasse LibClassA durch eine modifizierte Version ersetzt.
Die modifizierte Klasse LibClassA ist in der Datei Aufgabe_7_1_Update.zip auf der VeranstaltungsHomepage bereitgestellt. Welche drei Fehler bzw. Probleme entstehen durch dieses Update im
Zusammenspiel zwischen dem Bibliotheks-Code und dem Applikations-Code? Beachten Sie, dass
die Bibliotheksentwickler nicht wissen, wie der Applikations-Code aussieht. Erläutern Sie jeweils,
wie sich das Problem auf die Ausführung des Programms auswirkt. Gehen Sie davon aus, dass
der gesamte Code in der Ausgangsform des Systems so beabsichtigt war.
3. Nachdem Sie im vorigen Aufgabenteil die Probleme identifiziert haben, die durch das BibliotheksUpdate entstanden sind, sollen Sie diese jetzt beheben. Obwohl die externe Bibliothek als Quelltext vorliegt, sind die Korrekturen ausschließlich im Applikations-Code vorzunehmen, damit auch
künftig weiter Bibliotheks-Updates eingespielt werden können. Geben Sie eine korrigierte Version des Applikations-Codes an, in der die drei neu entstandenen Probleme so weit wie möglich
behoben sind (Sie können dabei auch neue Klassen im Applikations-Code hinzufügen).
4. Wie hätte man durch geeignete Maßnahmen (sofern es solche gibt) im Applikations-Code, also in
der Klasse OwnClass, vorab diese Probleme verhindern können oder zumindest erreichen können,
dass diese frühzeitig (durch den Compiler) erkannt worden wären.
Hinweis: Beachten Sie unter anderem die Möglichkeiten der Standard-Annotationen in Java.
Aufgabe 7.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Punkte
In dieser und den nächsten beiden Aufgaben werden einige Konzepte der funktionalen Programmierung,
die in der Vorlesung vorgestellt worden sind, an Hand von Beispielen in der rein-funktionalen Programmiersprache Haskell vertiefend betrachtet. Es werden keine Vorkenntnisse in Haskell oder einer anderen
funktionalen Sprache vorausgesetzt. Alle Informationen, die Sie zur Bearbeitung der Aufgaben benötigen, finden Sie im Vorlesungsskript und in einem Haskell-Tutorial, das auf der Veranstaltungs-Homepage
1
als Material zu dieser Übung bereitgestellt ist (HaskellTutorial.pdf). Arbeiten Sie zunächst dieses Tutorial durch, bevor Sie die Beantwortung der folgenden Fragen angehen.
Wenn Sie die Haskell-Beispiele ausprobieren möchten, installieren Sie am besten den Haskell-Interpreter
Hugs. Auf http://www.haskell.org/hugs sind Installationspakete für diverse Plattformen verfügbar.
1. Geben Sie ein Haskell-Ausdruck an, der eine Liste mit den Integer-Elementen 13, 76, 5, 99 und
27 in dieser Reihenfolge erzeugt (zu Listen in Haskell siehe Abschnitt 2.2.5 im Tutorial).
2. Geben Sie ein Haskell-Ausdruck an, der ein 5-Tupel mit den Elementen ’p’, 5.87, "xyz", 84 und
1.3 in dieser Reihenfolge erzeugt (zu Tupeln in Haskell siehe Abschnitt 2.2.6 im Tutorial).
3. Geben Sie eine Haskell-Funktion createList_x an, die einen Integer-Wert als Parameter entgegennimmt und als Resultat eine Integer-Liste zurückliefert, die fünf mal genau diesen Integer-Wert
enthält, so dass z.B. der Funktionsaufruf createList_x 7 die Liste [7, 7, 7, 7, 7] als Resultat liefert. Ihre Funktionsdefinition soll sowohl die Typdeklaration der Funktion als auch deren
Implementierung umfassen. Haskell-Funktionen sind in den Abschnitten 1.3 und 2.3 im Tutorial beschrieben, diverse Beispiele zu Funktionen mit Listen als Rückgabewerten finden Sie in
Abschnitt 3.2.
4. Schreiben Sie eine Haskell-Funktion createList_x_n, die eine Liste mit n Wiederholungen eines
Integer-Werts x erzeugt und als Resultat zurückliefert. Diese Funktion soll zwei Integer-Parameter
entgegennehmen, mit dem ersten Parameter wird der Wert für x übergeben, mit dem zweiten der
Wert für n. Geben Sie auch die Typdeklaration der Funktion createList_x_n an.
Hinweis: Verwenden Sie zum Konstruieren der Liste Rekursion (siehe Abschnitt 2.7 im Tutorial).
5. In Haskell kann eine Funktion partiell ausgewertet werden, indem sie nur mit einem Teil ihrer
Parameter ”aufgerufen” wird. Dabei entsteht eine neue Funktion, deren Signatur nur noch die
restlichen Parameter umfasst.
Implementieren Sie eine Haskell-Funktion createList_37_n mit einem Integer-Parameter n, die
eine Liste mit n Wiederholungen der Integer-Zahl 37 erzeugt und als Resultat zurückliefert. Definieren Sie dazu createList_37_n als partielle Auswertung der Funktion createList_x_n aus
dem vorigen Aufgabenteil, wobei Sie nur einen aktuellen Parameter an createList_x_n übergeben (weitere Details zu partieller Auswertung finden Sie in Abschnitt 2.6 im Tutorial).
Geben Sie auch die Typdeklaration der Funktion createList_37_n an.
Aufgabe 7.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Punkte
Gegeben sei folgenes Haskell-Programm:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
fzip :: [Int] -> [Int] -> (Int -> Int -> Int) -> [Int]
fzip [] [] _ = []
fzip (head1:tail1) (head2:tail2) f = (f head1 head2) : (fzip tail1 tail2 f)
fold :: [Int] -> Int -> (Int -> Int -> Int) -> Int
fold [] unit _ = unit
fold (head:tail) unit f = f head (fold tail unit f)
add :: Int -> Int -> Int
add x y = x + y
mult :: Int -> Int -> Int
mult x y = x * y
calc :: [Int] -> [Int] -> Int
calc m n = fold (fzip m n mult) 0 add
1. Was berechnet und liefert dieses Haskell-Programm, wenn man es mit dem Funktionsaufruf
calc [4, 3, 7] [9, 5, 2] startet?
2. Welche der Funktionen dieses Haskell-Programms sind Funktionen höherer Ordnung?
2
3. Beschreiben Sie, welche Funktionalität durch die Funktionen zip, fold, add, mult und calc jeweils
realisiert ist, und erläutern Sie, wie diese Funktionen funktionieren.
4. Konvertieren Sie das gegebene Haskell-Programm in ein äquivalentes Java-Programm.
a) Implementieren Sie dazu eine Java-Klasse Aufgabe_7_3, die die statischen Methoden zip,
fold, add, mult und calc enthält. Diese Methoden sollen jeweils die gleiche Funktionalität
realisieren wie die gleichnamigen Haskell-Funktionen.
b) Setzen Sie Haskell-Listen mit der Java-Standardklasse Vector um, die bereits in den vorigen
Übungen verwendet wurde.
Aufgabe 7.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Punkte
Eine quadratische Polynomfunktion lässt sich im Allgemeinen durch eine Funktion der Form
f (x) = c1 · x2 + c2 · x + c3 beschreiben. Zeichnet man den Funktionsgraphen einer solchen Funktion,
ergibt sich eine Parabel.
1. Implementieren Sie eine Haskell-Funktion f1, die entsprechend der obigen Definition den Funktionswert einer quadratischen Polynomfunktion mit den Koeffizienten c1, c2, und c3 an der Stelle x
berechnet und zurückgibt. f1 soll zwei Parameter entgegennehmen, einen für die Koeffizienten c1,
c2, und c3, wobei die Koeffizienten zu einem Tupel zusammengefasst sind, und einen Parameter
für die Auswertungsstelle x.
Geben Sie auch die Typdeklaration der Funktion f1 an (es soll mit dem Gleitkommazahlentyp
Float gerechnet werden).
2. Wendet man vor der Auswertung der Funktion f(x) jeweils eine Modifikationsfunktion g auf x an
( f(g(x)) ), so kann man die zugehörige Parabel entlang der x-Achse verschieben, strecken und
stauchen. Implementieren Sie eine Haskell-Funktion f2 als Erweiterung von f1, die als Funktion
höherer Ordnung eine Funktion g, die von Float auf Float abbildet, als zusätzlichen Parameter
entgegennimmt. Bei der Berechnung der Funktionswerte in f2 ist nun bei allen Vorkommen von
x zunächst die Parameterfunktion g auf x anzuwenden. Auf diese Weise lassen sich beliebige
Modifikationen an den x-Werten erreichen, indem man eine entsprechende Modifikationsfunktion
g an f2 übergibt.
Geben Sie auch die Typdeklaration der Funktion f2 an.
Details zu Funktionen höherer Ordnung finden Sie im Abschnitt 3.2 im Tutorial.
3. Die Funktion f2 aus dem vorigen Aufgabenteil soll nun verwendet werden, um eine Parabel
a) um shift Einheiten nach rechts zu verscheiben, indem x durch x - shift ersetzt wird,
b) um den Faktor stretch gestaucht werden, indem x durch x * shift ersetzt wird (es soll
vernachlässigt werden, dass es bei Parabeln, deren Scheitelpunkt nicht auf der y-Achse liegt,
hierbei auch zu einer Verschiebung kommt).
Definieren Sie für beide Modifikationen jeweils eine Haskell-Funktion g, die x in einen modifizierten
Wert transformiert, und geben Sie jeweils ein Beispiel an, in dem f2 mit g als Parameterfunktion
aufgerufen wird.
3
Herunterladen