Referentielle Transparenz und Monaden
Absolute Bezeichner
- In einem mathematischen Text wird der Wert eines absoluten Bezeichners genau einmal definiert.
- a ≔ 2.
Verwendung eines Bezeichners
- Ein Bezeichner kann verwendet werden. Dann steht er für seinen Wert.
- a ≔ 2.
b ≔ a.
c ≔ b.
In dem angegebenen Text hat der Bezeichner "b" in "c ≔ b." den Wert "2", da in der Definition von "b" der Bezeichner "a" für den Wert "2" stand.
Referentielle Transparenz
Die referentielle Transparenz ist die Eigenschaft eines Terms in einer Äußerung, der folgenden Aussage zu genügen: „Eine Äußerung ändert ihre Bedeutung nicht, wenn ein darin vorkommender Term durch einen anderen wertgleichen Term ersetzt wird.“
Diese Aussage muß aber mit Vorsicht eingesetzt werden. Ersetzt man etwa in der Definition "a ≔ 2." den Bezeichner "a" durch den wertgleichen Term "2", so entsteht "2 ≔ 2.", was offensichtlich etwas anderes bedeutet als "a ≔ 2.".
Um dieses Problem zu umgehen wird das Vorkommen von "a" auf der linken Seite von " ≔ " als eine Angabe des Bezeichners selber angesehen, aber nicht als eine Verwendung. Eine Verwendung ist dabei eine Situation, in der ein Term für seinen Wert steht.
Die Eigenschaft der referentiellen Transparenz lautet dann „Eine Äußerung ändert ihre Bedeutung nicht, wenn eine Verwendung eines Terms in der Äußerung durch einen Verwendung eines gleichwertigen Terms ersetzt wird.“
Ein Spezialfall der referentiellen Transparenz für numerische Terme, ist die Möglichkeit die Verwendung eines Terms durch ein gleichwertiges Numeral zu ersetzen. Diese Eigenschaft ist die numerische referentielle Transparenz.
Parameter
- Die Kenntnis der Bedeutung des Parameters "x " in einer Definition wie der folgenden wird hier als bekannt vorausgesetzt.
- f ≔ λx . 2 · x.
Inwiefern gilt die numerische referentielle Transparenz nun für Parameter? Diese können nicht durch ein wertgleiches Numeral ersetzt werden—sie haben keines! Denn sie haben keinen Wert, der an der Stelle der obigen Definition bestimmt ist.
- In dem folgenden Text wird die Abbildung "f" zweimal angewendet.
- f ≔ λx . 2 · x.
a ≔ f( 2 ).
b ≔ f( 3 ). - Informell könnte man sagen, daß der Parameter "x " in jeder Anwendung einen bestimmten Wert habe. Die referentielle Transparenz erlaubt nämlich die Umformung der Äußerung in die folgende Äußerung.
- a ≔ (λx . 2 · x )( 2 ).
b ≔ (λx . 2 · x )( 3 ).
Hier sind nun zwei Kopien des ursprünglichen Lambda-Ausdrucks entstanden und informell kann man jetzt sagen, daß der Parameter "x " unter Berücksichtigung der Anwendung auf das Argument in jeder Kopie einen bestimmten Wert habe. Im ursprünglichen Text hat das "x " in "f ≔ λx . 2 · x." aber sicher nicht einen bestimmten Wert.
Man kann nun also festhalten, daß die numerische referentielle Transparenz nicht auf Parameter und von ihnen abhängige Terme anwendbar ist, da Parameter im allgemeinen einfach keinen bestimmten Wert haben, durch den sie ersetzt werden könnten.
Einen Bezeichner, der ein Parameter ist, soll ein abstrakter Bezeichner genannt werden. Jeder Term, dessen Wert vom Wert solch eines Bezeichners abhängt, soll ein abstrakter Term genannt werden. Jeder andere Bezeichner hat einen bestimmten Wert und wird absoluter Bezeichner genannt. Jeder andere Term hat einen bestimmten Wert und wird absoluter Term genannt.
Die Regel für die numerische referentielle Transparenz lautet damit „Eine Äußerung ändert ihre Bedeutung nicht, wenn eine Verwendung eines absoluten Bezeichners in der Äußerung durch ein wertgleiches Numeral ersetzt wird.“. Eine entsprechende referentielle Transparenz gilt auch für Terme: „Eine Äußerung ändert ihre Bedeutung nicht, wenn eine Verwendung eines absoluten Term in der Äußerung durch ein Numeral mit dem Wert dieses absoluten Terms ersetzt wird.“
Die monadische Bindung
Das Verständnis der beschriebenen Sonderrolle von Parametern hinsichtlich der numerischen referentiellen Transparenz ist nun auch der Schlüssel zum Verständnis der Art und Weise, wie die monadische Verbindung in funktionalen Sprachen die referentielle Transparenz in Zusammenhang mit der EA-Monade wahrt.
Durch die monadische Bindung kann das Produkt einer EA-monadischen Operation nur den Wert eines abstrakten Bezeichners oder Terms festlegen, aber nicht den Wert eines absoluten Bezeichners oder Terms. Kurz gesagt: Produkte können nur an Parameter gebunden werden. Da die numerische referentielle Transparenz in der Mathematik aber nur absolute Bezeichner und Terme betrifft, wird sie durch diese Art der Bindung nicht gestört.
Mit Programmiersprachen möchte man auch die Messung physikalischer Prozesse beschreiben, deren Zustände eben zeitlich veränderlich sind, so daß ein Einlesen bei jedem Mal einen anderen Wert ergeben kann. Mit mathematischen absoluten Bezeichnern sind solche Messungen schlecht verträglich, da ein absoluter Bezeichner ja nur einen Wert in einem Text haben kann. Es zeigt sich aber, daß es auch in der Mathematik Bezeichner gibt, die in einem Text eben nicht nur genau einen bestimmten Wert haben, nämlich die Parameter. Die parametrisierten Lambda-Ausdrücke können in der Mathematik wiederholt auf verschiedene Argumente angewendet werden und dabei sozusagen bei jedem Mal einen anderen Wert annehmen. Damit bietet es sich geradezu an, Meßwerte an diese zu binden, wenn man die mathematische Sprache weiterhin verwenden will, und genau das leistet die EA-Monade.
Die Anwendung eines Lambda-Ausdrucks auf ein Argument mit der Festlegung des noch offengelassenen Parameterwerts durch den Argumentwert modelliert das Einlesen eines Wertes durch ein Programm. Die Bezeichner der Mathematik erlauben das „Kopieren“ eines Lambda-Ausdrucks durch mehrfache Verwendung des Namens: Dem entspricht das Kopieren eines Aktivierungsverbundes beim Erzeugen eines Prozedurexemplars oder das Anlegen eines neuen Exemplars einer Klasse. Es zeigt sich damit, daß viele Prozesse selbst prozeduraler oder objektorientierter Programmiersprache insofern recht analog zu klassischen mathematischen Auffassungen sind, wenn man die Analogien nur auf die rechte Weise herstellt.
Ausrechnen einer Anwendung
Eine Operation "O" ist ein Paar "(p,n)" von zwei Abbildungen eines Vorzustandes aus der Zustandsmenge "Z" in einen Wert aus einer Wertemenge "W" (das Produkt der Operation) und einen Nachzustand aus der Zustandsmenge "Z".
Für einen numerischen Speicher sei die Zustandsmenge beispielsweise das ganzzahlige Intervall "[0,256)".
- Die stabile Leseoperation "L" ist durch die beiden folgenden Abbildungen gegeben:
- Lp: Z → W, s ↦ s
- Ln: Z → Z, s ↦ s
- Die neutrale Schreiboperation "S(w)" ist für jeden Wert "w" durch die beiden folgenden Abbildungen gegeben:
- S(w)p: Z → W, s ↦ w
- S(w)n: Z → Z, s ↦ w
Damit wird die Abbildung "S: w ↦ S(w )" als eine parametrisierte Operation angesehen, also eine Abbildung, die jedem Parameterwert "w " eine Schreiboperation "S(w )" zuordnet.
- Die monadische Verbindung " ; " einer Operationen "A" und einer parametrisierten Operation "B" ist definiert durch:
- ; : OT ₀ × (T ₀ → OT ₁ ) → OT ₁ ,
- (A ; B)s = B(Ap(s ))An(s ).
Nun soll als Anwendungsbeispiel das Produkt und der Nachzustand einer Operation unter Ausnutzung der referentiellen Transparenz ausgerechnet werden.
- Die Operation D sei gegeben durch
- D ≔( L ; λx . S(2 · x )).
Diese Operation liest einen Wert aus dem Speicher und schreibt das Doppelte (im Sinne der üblichen Restklassenarithmetik) zurück.
Es soll der Wert der Anwendung "D s" dieser Operation "D" auf den Zustand "s" ermittelt werden.
- Ersetzt man das "D" in "D s" durch die obige Definition von "D" so ergibt sich:
- (L ; λx . S(2 · x ))s.
- Die Anwendung der obenstehenden Definition der monadischen Verbindung " ; " liefert
- (λx . S(2 · x ))(Lp(s))Ln(s).
- Nun kann die Definition der Abbildung "Lp" und der Abbildung "Ln" verwendet werden:
- (λx . S(2 · x ))(s)s
- Die Reduktion der Lambda-Abstraktion ist jetzt ebenfalls möglich:
- S(2 · s)s
- Die Operation "S(2 · s)" wird durch ihr Komponente "S(2 · s)p" und ihre Komponente "S(2 · s)n" dargestellt:
- (S(2 · s)p s, S(2 · s)n s)
- Nun kann die Definition dieser beiden Komponenten direkt eingesetzt werden und es ergibt sich
- (2 · s, 2 · s).
Wir wissen jetzt also, daß das Produkt und der Nachzustand der Operation "D" jeweils durch das Zweifache des Vorzustandes gegeben sind und haben diese damit explizit ausgerechnet.
Dabei wurde durch das wiederholte Einsetzen wertgleicher Terme von der referentiellen Transparenz Gebrauch gemacht. Bei den obigen Schritten gibt es auch noch eine gewisse Freiheit der Wahl einer Reihenfolge: Einige Schritte könnten umgeordnet werden. All dies ist ein rein mathematisches Vorgehen, an keiner Stelle wurde operationale Semantik verwendet oder ein zeitlicher Ablauf von Operationen zugrundegelegt.
Das Wort „Transparenz“
Mit dem Wort „Transparenz“ bringt man zum Ausdruck, daß ein Term selber sozusagen „durchsichtig“ ist, da man ihn nur benutzt, um durch ihn hindurch den Wert zu sehen. In dem Term "a + f(2) · g(3)" kann man etwa den zweiten Summanden verändern und erhält so den gleichwertigen Term "a + g(3) · f(2)", die genaue Schreibweise dieses Terms ist also irrelevant: Man sieht nicht den Term, sondern den Wert, damit ist der Term quasi durchsichtig und gibt den Blick auf den hinter ihm liegenden Wert frei. Man ist frei den Term umzustellen, solange die Wertgleichheit dabei beachtet wird.
In einer prozessualen Programmiersprache ist die referentielle Transparenz verletzt. Wird der Ausdruck "a+f( 2 )*g( 3 )" durch den Ausdruck "a+g( 3 )*f( 2 )" ersetzt, so kann sich sein Wert ändern, wenn sich dadurch die Reihenfolge der Auswertung ändert und somit Wirkungen in anderer Reihenfolge auftreten, die Wert von Teilausdrücken beeinflussen können. Man kann also dort nicht mehr durch die Schreibweise „hindurchsehen“, sondern muß sich mit ihr befassen: Sie ist opak.