Ein- und Ausgabe in Gofer
Next: Dialogues
Up: Gofer-Kurzübersicht
Previous: Layout rules -
Von einem Programm, das über I/O Operationen mit dem Betriebssystem
kommuniziert haben wir in der Regel die folgende Vorstellung:
(print stdout "Geben sie eine Zahl ein");
(read stdin number);
(print stdout "das Quadrat von ");
(print stdout (int2string number));
(print stdout "ist: ");
(print stdout (int2string (square number)))
Von derartigen Programmen interessiert nicht mehr der Wert einer Funktion
sondern ihr Seiteneffekt, in Form eines Bildschirmausdrucks oder einer
geänderten Datei. Reines funktionales Programmieren ist aber auf das
Programmieren ohne Seiteneffekte ausgelegt.
Unsere Vorstellung von Input/Output Operationen widerspricht so dem
funktionalen Paradigma im Wesentlichen an zwei Punkten.
-
referentielle Transparenz
I/O kann als ein Kommunikationsprozess zwischen einem Programm und
dem Betriebssystem betrachtet werden.
Das Programm schickt so zB mit einem readfile
Befehl eine Botschaft an das Betriebssystem, die je nach Status des
Filesystems mit einem bestimmten String oder aber einer Fehlermeldung
vom System beantwortet wird. Betrachten wir den readfile Befehl
als eine Funktion, die als Wert die Antwort des Betriebssystems hat, so
verletzt diese Funktion die Forderung nach referentieller Transparenz.
Je nach dem Status des Filesystems kann derselbe Funktionsaufruf
(readfile datei) verschiedene Werte bekommen, abhängig davon,
ob die Datei existiert, gelesen werden darf, gelesen werden kann und
welcher Text unter datei abgespeichert ist. Diese sind alles dem
Programm unbekannte Zustände.
-
Auswertungsreihenfolge
Als zweite Schwierigkeit stellt sich die Frage der Auswertungsreihenfolge:
Lazy funktionale Sprachen sind gerade so konzipiert, dadie
Auswertungsreihenfolge der einzelnen Redexe im Programmablauf streng
nach der Notwendigkeit gesteuert wird. Erst wenn der Wert eines
Ausdrucks in Normalform benötigt wird, wird dieser auch ausgewertet.
Bei I/O Funktionen im klassischen Sinn interessiert weniger der Wert der
Funktion sondern der durch sie hervorgerufene Seiteneffekt.
Es kann dem Programmierer schon
mitunter entgehen, dader Wert eines write Befehls zur
Programmevaluierung nicht benötigt wird und so dieser auch nicht ausgeführt
wird.
Ein Codeoptimierer könnte unter Umständen eine zweimalige Abfrage an
den Benutzer wegoptimieren, da sie über denselben Ausdruck, der aber
verschiedene Werte erwartet realisiert wird.
Im allgemeinen haben wir von I/O Prozessen die Vorstellung einer Sequenz
einzelner I/O Befehle. Lazy funktionale Sprachen wollen aber
Sequenzialisierung möglichst nicht erzwingen. So wird auch kein
expliziter Sequenzoperator wie in imperativen Sprachen (C, Pascal) aber
auch in strikten funktionalen Sprachen (Scheme) zur Verfügung gestellt.
Wir können von lazy funktionale Sprachen also nicht mit dem uns vertrauten
I/O Routinen rechnen.
Betrachten wir nun verschiedene Lösungen des I/O Problems in
Gofer/Haskell.
Next: Dialogues
Up: Gofer-Kurzübersicht
Previous: Layout rules -
Sven Eric Panitz
Mi., 01. Nov. 1995, 12:17:13