it-swarm.com.de

Was ist referenzielle Transparenz?

Was macht der Begriff? referenzielle Transparenz bedeuten? Ich habe gehört, dass es als "es bedeutet, dass Sie Gleiche durch Gleiche ersetzen können" beschrieben wird, aber dies scheint eine unzureichende Erklärung zu sein.

254
Claudiu

Der Begriff "referenzielle Transparenz" kommt von analytischer Philosophie , dem Zweig der Philosophie, der natursprachliche Konstrukte, Aussagen und Argumente basierend auf den Methoden der Logik und Mathematik analysiert. Mit anderen Worten, es ist das außerhalb der Informatik am nächsten kommende Fach der Programmiersprachensemantik . Der Philosoph Willard Quine war für die Initiierung des Konzepts der referenziellen Transparenz verantwortlich, war aber auch in den Ansätzen von Bertrand Russell und Alfred Whitehead implizit enthalten.

Im Kern ist "referenzielle Transparenz" eine sehr einfache und klare Idee. Der Begriff "referent" wird in der analytischen Philosophie verwendet, um über das, worauf sich ein Ausdruck beziehtzu sprechen. Es ist ungefähr dasselbe, was wir in der Semantik der Programmiersprache unter "Bedeutung" oder "Bezeichnung" verstehen. Am Beispiel von Andrew Birkett ( blog post ) bezieht sich der Begriff "Hauptstadt von Schottland" auf die Stadt Edinburgh. Das ist ein einfaches Beispiel eines "Referenten".

Ein Kontext in einem Satz ist "referenziell transparent", wenn ein Begriff in diesem Kontext durch einen anderen Begriff ersetzt wird, der bezieht sich auf dieselbe Entität die Bedeutung nicht ändert. Zum Beispiel

Das schottische Parlament trifft sich in der Hauptstadt von Schottland.

bedeutet das Gleiche wie

Das schottische Parlament trifft sich in Edinburgh.

Der Kontext "Das schottische Parlament trifft sich in ..." ist also ein referenziell transparenter Kontext. Wir können "die Hauptstadt Schottlands" durch "Edinburgh" ersetzen, ohne die Bedeutung zu ändern. Anders ausgedrückt: Der Kontext kümmert sich nur darum, worauf sich der Begriff bezieht, und nichts anderes. Das ist der Sinn, in dem der Kontext "referenziell transparent" ist.

Auf der anderen Seite im Satz,

Edinburgh ist seit 1999 die Hauptstadt Schottlands.

wir können einen solchen Ersatz nicht machen. Wenn wir das taten, würden wir "Edinburgh ist seit 1999 Edinburgh seit 1999" bekommen, was eine verrückte Aussage ist und nicht die gleiche Bedeutung wie der ursprüngliche Satz vermittelt. Es scheint also, dass der Kontext "Edinburgh ist seit 1999" referenziell undurchsichtig (das Gegenteil von referenziell transparent) ist. Es ist anscheinend wichtig für etwas mehr als das, worauf sich der Begriff bezieht. Was ist es?

Dinge wie "die Hauptstadt von Schottland" werden bestimmte Begriffe genannt, und sie gaben Logikern und Philosophen lange Zeit keinen mageren Kopfschmerz. Russell und Quine haben sie aussortiert und gesagt, dass sie nicht wirklich "referentiell" sind, d. H., Es ist ein Fehler zu glauben, dass die obigen Beispiele verwendet werden, um sich auf Entitäten zu beziehen. Der richtige Weg, um zu verstehen "Edinburgh ist seit 1999 Hauptstadt von Schottland" ist zu sagen

Schottland hat seit 1999 eine Hauptstadt und diese Hauptstadt ist Edinburgh.

Dieser Satz kann nicht in einen verrückten Satz umgewandelt werden. Problem gelöst! Der Sinn von Quine war zu sagen, dass die natürliche Sprache unordentlich oder zumindest kompliziert ist, weil sie für den praktischen Gebrauch geeignet ist, aber Philosophen und Logiker sollten Klarheit schaffen, indem sie sie auf die richtige Weise verstehen. Referenzielle Transparenz ist ein Werkzeug, das verwendet wird, um solche Klarheit der Bedeutung zu bringen.

Was hat das alles mit dem Programmieren zu tun? Eigentlich nicht sehr viel. Wie gesagt, referenzielle Transparenz ist ein Werkzeug, das zum Verstehen der Sprache verwendet wird, d. H. Bei der Zuweisung von Bedeutung. Christopher Strachey , der das Gebiet der Semantik von Programmiersprachen begründete, verwendete es in seiner Bedeutungsforschung. Sein Gründungspapier " Grundbegriffe in Programmiersprachen " ist im Web verfügbar. Es ist eine schöne Arbeit, die jeder lesen und verstehen kann. Also bitte. Sie werden viel erleuchtet sein. Er führt in diesem Absatz den Begriff "referenzielle Transparenz" ein:

Eine der nützlichsten Eigenschaften von Ausdrücken ist die von Quine referential Transparenz. Im Wesentlichen bedeutet dies, dass, wenn wir den Wert eines Ausdrucks finden wollen, der Enthält einen Unterausdruck. Das einzige, was wir über den Unterausdruck wissen müssen, ist dessen Wert. Alle anderen Merkmale des Unterausdrucks, z. B. seine interne Struktur, die Nummer und die Art seiner Komponenten, die Reihenfolge, in der sie bewertet werden, oder die Farbe der Tinte. in denen sie geschrieben werden, sind für den Wert des Hauptausdrucks irrelevant.

Die Verwendung von "im Wesentlichen" legt nahe, dass Strachey es umschreibt, um es in einfachen Worten zu erklären. Funktionale Programmierer scheinen diesen Absatz auf ihre Art zu verstehen. Es gibt neun weitere Fälle von "referenzieller Transparenz" in der Zeitung, aber sie scheinen sich nicht um die anderen Gedanken zu kümmern. Tatsächlich widmet sich der gesamte Artikel von Strachey der Erklärung der Bedeutung von imperativen Programmiersprachen. Heute behaupten funktionale Programmierer, dass imperative Programmiersprachen nicht referentiell transparent sind. Strachey würde sich in seinem Grab umdrehen.Wir können die Situation retten. Wir haben gesagt, dass die natürliche Sprache "unordentlich oder zumindest kompliziert" ist, weil sie für den praktischen Gebrauch praktisch ist. Programmiersprachen sind genauso. Sie sind "unordentlich oder zumindest kompliziert", weil sie für den praktischen Gebrauch praktisch sind. Das heißt nicht, dass sie uns verwirren müssen. Sie müssen nur auf die richtige Weise verstanden werden, indem sie eine Metasprache verwenden, die referenziell transparent ist, so dass wir Klarheit über die Bedeutung haben. In der von mir zitierten Zeitung tut Strachey genau das. Er erklärt die Bedeutung imperativer Programmiersprachen, indem er sie in elementare Konzepte zerlegt und dabei niemals an Klarheit verliert. Ein wichtiger Teil seiner Analyse besteht darin, darauf hinzuweisen, dass Ausdrücke in Programmiersprachen zwei Arten von "Werten" haben, die als l-values und r-values bezeichnet werden. Vor Stracheys Papier wurde dies nicht verstanden und Verwirrung herrschte. Heute wird C in der Definition von C routinemäßig erwähnt, und jeder C-Programmierer versteht den Unterschied. (Ob die Programmierer in anderen Sprachen das genauso gut verstehen, ist schwer zu sagen.).

Sowohl Quine als auch Strachey beschäftigten sich mit der Bedeutung von Sprachkonstruktionen, die eine Art Kontextabhängigkeit beinhalten. Unser Beispiel "Edinburgh ist seit 1999 Hauptstadt von Schottland" bedeutet beispielsweise, dass "Hauptstadt von Schottland" von dem Zeitpunkt abhängt, zu dem sie in Betracht gezogen wird. Eine solche Kontextabhängigkeit ist sowohl in natürlichen als auch in Programmiersprachen eine Realität. Selbst in der funktionalen Programmierung sind freie und gebundene Variablen in Bezug auf den Kontext zu interpretieren, in dem sie erscheinen. Die Kontextabhängigkeit jeglicher Art blockiert die referenzielle Transparenz auf die eine oder andere Weise. Wenn Sie versuchen, die Bedeutung von Begriffen ohne Rücksicht auf die Kontexte, von denen sie abhängig sind, zu verstehen, würden Sie erneut zu Verwirrung führen. Quine beschäftigte sich mit der Bedeutung von Modal Logic. Er vertrat die Ansicht, dass modale Logik referenziell undurchsichtig sei, und es sollte bereinigt werden, indem es in einen referenziell transparenten Rahmen übersetzt wird (z. B. indem er die Notwendigkeit als Beweisbarkeit betrachtet). Diese Debatte hat er weitgehend verloren. Für Logiker und Philosophen war Kripkes mögliche Weltsemantik vollkommen ausreichend. Eine ähnliche Situation herrscht auch bei der imperativen Programmierung vor. Die durch Strachey erklärten Zustandsabhängigkeit und die von Reynolds (ähnlich wie bei Kripkes möglicher Weltsemantik) erläuterte Ladenabhängigkeit sind vollkommen ausreichend. Funktionale Programmierer wissen nicht viel von dieser Forschung. Ihre Ideen zur referenziellen Transparenz sollen mit einem großen Salzkorn aufgenommen werden.

[Zusätzliche Anmerkung: Die obigen Beispiele zeigen, dass ein einfacher Ausdruck wie "Hauptstadt von Schottland" mehrere Bedeutungsebenen hat. Auf einer Ebene sprechen wir derzeit über die Hauptstadt. Auf einer anderen Ebene könnten wir über alle möglichen Hauptstädte sprechen, die Schottland im Laufe der Zeit gehabt haben könnte. Wir können in einen bestimmten Kontext hinein "zoomen" und "herauszoomen", um alle Kontexte in der normalen Praxis recht einfach abzudecken. Die Effizienz der natürlichen Sprache nutzt unsere Fähigkeit dazu. Imperative Programmiersprachen sind auf die gleiche Weise effizient. Wir können eine Variable x auf der rechten Seite einer Zuweisung (der r-Wert) verwenden, um über ihren Wert in einem bestimmten Zustand zu sprechen. Oder wir sprechen über seinen l-Wert, der alle Zustände umfasst. Die Leute werden von solchen Dingen selten verwirrt. Sie sind jedoch möglicherweise nicht in der Lage, alle Bedeutungsebenen von Sprachkonstrukten genau zu erklären. Alle diese Bedeutungsebenen sind nicht notwendigerweise "offensichtlich" und es ist eine Wissenschaftsfrage, sie richtig zu studieren. Die Unartikulation gewöhnlicher Menschen, solche geschichteten Bedeutungen zu erklären, bedeutet jedoch nicht, dass sie darüber verwirrt sind.].

Ein separates "Postscript" unten bezieht diese Diskussion auf die Bedenken der funktionalen und imperativen Programmierung.) _.

_{( A separate "postscript" below relates this discussion to the concerns of functional and imperative programming.

327
Uday Reddy

Referenzielle Transparenz, ein Begriff, der häufig in der Funktionsprogrammierung verwendet wird, bedeutet, dass bei einer Funktion und einem Eingabewert immer die gleiche Ausgabe erhalten wird. Das heißt, es wird kein externer Zustand in der Funktion verwendet.

Hier ist ein Beispiel für eine referenzielle transparente Funktion:

int plusOne(int x)
{
  return x+1;
}

Mit einer referenziellen transparenten Funktion können Sie diese Funktion bei Eingabe und Funktion durch einen Wert ersetzen, anstatt die Funktion aufzurufen. Anstatt plusOne mit einem Parameter von 5 aufzurufen, könnten wir dies einfach durch 6 ersetzen. 

Ein weiteres gutes Beispiel ist die Mathematik im Allgemeinen. In der Mathematik wird eine Funktion und ein Eingabewert immer auf denselben Ausgabewert abgebildet. f(x) = x + 1. Daher sind Funktionen in der Mathematik referenziell transparent. 

Dieses Konzept ist für Forscher wichtig, da es bedeutet, dass eine referenziell transparente Funktion für die automatische Parallelisierung und Zwischenspeicherung geeignet ist. 

Referenzielle Transparenz wird immer in funktionalen Sprachen wie Haskell verwendet.

-

Im Gegensatz dazu gibt es das Konzept der referentiellen Undurchsichtigkeit. Das bedeutet das Gegenteil. Beim Aufruf der Funktion wird möglicherweise nicht immer dieselbe Ausgabe erzeugt. 

//global G
int G = 10;

int plusG(int x)
{//G can be modified externally returning different values.
  return x + G;
}

Ein anderes Beispiel ist eine Member-Funktion in einer objektorientierten Programmiersprache. Elementfunktionen arbeiten im Allgemeinen mit ihren Elementvariablen und wären daher referenziell undurchsichtig. Elementfunktionen können jedoch natürlich referenziell transparent sein.

Ein weiteres Beispiel ist eine Funktion, die aus einer Textdatei liest und die Ausgabe druckt. Diese externe Textdatei kann sich jederzeit ändern, so dass die Funktion referenziell undurchsichtig ist. 

125
Brian R. Bondy

Eine referenziell transparente Funktion hängt nur von ihrer Eingabe ab.

83
Draemon

[Dies ist ein Nachtrag zu meiner Antwort vom 25. März, um die Diskussion näher an die Belange der funktionalen/imperativen Programmierung heranzuführen.]

Die Vorstellung der funktionalen Programmierer von referentieller Transparenz scheint sich vom Standardbegriff in drei Punkten zu unterscheiden:

  • Während die Philosophen/Logiker Begriffe wie "Referenz", "Bezeichnung", "Designatum" und " bedeutung " verwenden, verwenden funktionale Programmierer den Begriff "Wert". (Dies ist nicht ganz ihre Absicht. Ich stelle fest, dass Landin, Strachey und ihre Nachkommen auch den Begriff "Wert" verwendeten, um über Verweise/Bezeichnungen zu sprechen. Es mag nur eine terminologische Vereinfachung sein, die Landin und Strachey eingeführt haben, aber es scheint, als ob sie eine großer Unterschied bei naiver Verwendung.)

  • Funktionale Programmierer scheinen zu glauben, dass diese "Werte" innerhalb der Programmiersprache existieren, nicht außerhalb. Dabei unterscheiden sie sich sowohl von den Philosophen als auch von den Semantikern der Programmiersprache.

  • Sie scheinen zu glauben, dass diese "Werte" durch Evaluierung erhalten werden sollen.

In dem Wikipedia-Artikel über referentielle Transparenz heißt es beispielsweise heute Morgen:

Ein Ausdruck wird als referenziell transparent bezeichnet, wenn er durch seinen Wert ersetzt werden kann, ohne das Verhalten eines Programms zu ändern (mit anderen Worten, ein Programm mit den gleichen Effekten und Ausgaben auf der gleichen Eingabe).

Dies steht völlig im Widerspruch zu dem, was die Philosophen/Logiker sagen. Sie sagen, dass ein Kontext referenziell oder referenziell transparent ist, wenn ein Ausdruck in diesem Kontext durch einen anderen Ausdruck ersetzt werden kann, der sich auf dasselbe Koreferenz bezieht ) Ausdruck). Wer sind diese Philosophen/Logiker? Dazu gehören Frege , Russell , Whitehead , Carnap , Quine , Kirche und unzählige andere. Jeder von ihnen ist eine hoch aufragende Figur. Die kombinierte intellektuelle Kraft dieser Logiker ist gelinde gesagt weltbewegend. Sie alle sind sich einig, dass Referenzen/Bezeichnungen außerhalb der formalen Sprache existieren und Ausdrücke innerhalb der Sprache nur über sie sprechen können . Alles, was man in der Sprache tun kann, ist, einen Ausdruck durch einen anderen Ausdruck zu ersetzen, der sich auf dieselbe Entität bezieht. Die Referenzen/Bezeichnungen selbst existieren nicht in der Sprache. Warum weichen die funktionalen Programmierer von dieser etablierten Tradition ab?

Man könnte annehmen, dass die Semantiker der Programmiersprache sie in die Irre geführt haben. Aber das haben sie nicht.

Landin :

(a) jeder Ausdruck hat eine verschachtelte Unterausdrucksstruktur, (b) jeder Unterausdruck bezeichnet etwas (normalerweise eine Zahl, einen Wahrheitswert oder eine numerische Funktion) , (c) das, was ein Ausdruck bezeichnet, dh , sein "Wert", hängt nur von den Werten seiner Unterausdrücke ab, nicht von anderen Eigenschaften von ihnen. [Hervorhebung hinzugefügt]

Stoy :

Das einzige, was an einem Ausdruck wichtig ist, ist sein Wert, und jeder Unterausdruck kann durch jeden anderen Wert ersetzt werden [Hervorhebung hinzugefügt]. Außerdem ist der Wert eines Ausdrucks in gewissen Grenzen derselbe, wann immer er auftritt ".

Vogel und Wadler :

der Wert eines Ausdrucks hängt nur von den Werten seiner konstituierenden Ausdrücke ab (falls vorhanden), und diese Unterausdrücke können frei durch andere mit demselben Wert ersetzt werden [Hervorhebung hinzugefügt].

Rückblickend könnten die Bemühungen von Landin und Strachey, die Terminologie zu vereinfachen, indem "Referenz"/"Bezeichnung" durch "Wert" ersetzt wird, unklug gewesen sein. Sobald man von einem "Wert" hört, besteht die Versuchung, an einen Bewertungsprozess zu denken, der dazu führt. Es ist gleichermaßen verlockend, sich das, was die Bewertung ergibt, als "Wert" vorzustellen, auch wenn klar sein mag, dass dies nicht die Bezeichnung ist. Dies ist, wie ich zusammenfasse, dem Konzept der "referentiellen Transparenz" in den Augen von funktionalen Programmierern zugestoßen. Aber der "Wert", von dem die frühen Semantiker sprachen, ist nicht das Ergebnis einer Bewertung oder der Ausgabe einer Funktion oder dergleichen. Es ist die Bezeichnung des Begriffs.

Wenn wir den sogenannten "Wert" eines Ausdrucks ("Referenz" oder "Bezeichnung" im Diskurs der klassischen Philosophen) als komplexes mathematisch/konzeptuelles Objekt verstehen, eröffnen sich alle Arten von Möglichkeiten.

  • Strachey interpretierte Variablen in imperativen Programmiersprachen als L-Werte , wie in meiner Antwort vom 25. März erwähnt. Dies ist ein ausgeklügeltes konzeptionelles Objekt, das innerhalb der Syntax einer Programmiersprache keine direkte Darstellung hat .
  • Er interpretierte auch Befehle in solchen Sprachen als State-to-State-Funktionen, eine weitere Instanz eines komplexen mathematischen Objekts, das kein "Wert" innerhalb der Syntax ist.
  • Sogar ein nebenwirkender Funktionsaufruf in C hat einen genau definierten "Wert" als Zustandstransformator, der Zustände auf Paare von Zuständen und Werten abbildet (die sogenannte "Monade" in der Terminologie der funktionalen Programmierer).

Die Abneigung funktionaler Programmierer, solche Sprachen als "referenziell transparent" zu bezeichnen, impliziert lediglich, dass sie solche komplexen mathematisch/konzeptuellen Objekte nicht als "Werte" akzeptieren. Andererseits scheinen sie durchaus gewillt zu sein, einen Zustandstransformator als "Wert" zu bezeichnen, wenn er in ihrer eigenen Lieblingssyntax geschrieben und mit einem Modewort wie "Monade" versehen ist. Ich muss sagen, dass sie völlig inkonsistent sind, auch wenn wir ihnen zugestehen, dass ihre Vorstellung von "referentieller Transparenz" eine gewisse Kohärenz aufweist.

Ein bisschen Geschichte könnte Aufschluss darüber geben, wie diese Verwirrungen entstanden sind. Die Zeit von 1962 bis 1967 war für Christopher Strachey sehr intensiv. Von 1962 bis 1965 arbeitete er nebenbei als wissenschaftlicher Mitarbeiter bei Maurice Wilkes, um die Programmiersprache CPL zu entwerfen und zu implementieren. Dies war eine zwingende Programmiersprache, sollte aber auch leistungsstarke funktionale Programmiersprachen bieten. Landin, der in seiner Beratungsfirma für Strachey tätig war, hatte großen Einfluss auf Stracheys Sicht auf Programmiersprachen. In der wegweisenden Arbeit " Next 700 programming languages " von 1965 wirbt Landin unverhohlen für funktionale Programmiersprachen (bezeichnet sie als denotative Sprachen) und beschreibt imperative Programmiersprachen als ihre "Antithese ". In der folgenden Diskussion wird Strachey die starke Position von Landin in Zweifel ziehen.

... DLs bilden eine Teilmenge aller Sprachen. Sie sind eine interessante Untergruppe, aber eine, deren Verwendung unbequem ist, es sei denn, Sie sind daran gewöhnt. Wir brauchen sie, weil wir im Moment nicht wissen, wie man Beweise mit Sprachen konstruiert, die Imperative und Sprünge enthalten. [Hervorhebung hinzugefügt]

1965 übernahm Strachey die Position eines Readers in Oxford und scheint im Wesentlichen Vollzeit an der Entwicklung einer Theorie der Imperative und Sprünge gearbeitet zu haben. Bis 1967 war er mit einer Theorie fertig, die er in seinem Kurs über " Grundbegriffe in Programmiersprachen " an einer Kopenhagener Sommerschule unterrichtete. Die Vorlesungsunterlagen hätten veröffentlicht werden sollen, aber "leider wurde das Verfahren wegen des Dilatators nie durchgeführt; wie viele Arbeiten von Strachey in Oxford hatte die Zeitung jedoch eine einflussreiche private Verbreitung." ( Martin Campbell-Kelly )

Die Schwierigkeit, an Stracheys Schriften zu kommen, könnte dazu geführt haben, dass sich die Verwirrung verbreitete und die Menschen auf Sekundärquellen und Hörensagen angewiesen waren. Da " Fundamental concepts " jetzt im Web verfügbar ist, müssen Sie nicht mehr auf Vermutungen zurückgreifen. Wir sollten es lesen und uns überlegen, was Strachey meinte. Im Speziellen:

  • In Abschnitt 3.2 befasst er sich mit "Ausdrücken", in denen er über "R-Wert referentielle Transparenz" spricht.
  • In Abschnitt 3.3 geht es um "Befehle", in denen er von "L-wertiger referentieller Transparenz" spricht.
  • In Abschnitt 3.4.5 spricht er über "Funktionen und Routinen" und erklärt, dass "jede Abweichung der referenziellen Transparenz von R-Werten in einem R-Wert-Kontext beseitigt werden sollte, indem der Ausdruck in mehrere Befehle und einfachere Ausdrücke zerlegt wird, oder wenn das stellt sich als schwierig heraus, das Thema eines Kommentars. "

Jede Rede von "referentieller Transparenz", ohne die Unterscheidung zwischen L-Werten, R-Werten und anderen komplexen Objekten zu verstehen, die das konzeptuelle Universum des imperativen Programmierers bevölkern, ist grundsätzlich falsch.

71
Uday Reddy

Ein Ausdruck ist referenziell transparent, wenn er durch seinen Wert ersetzt werden kann, ohne den Algorithmus zu ändern, wodurch ein Algorithmus entsteht, der die gleichen Auswirkungen hat und für dieselbe Eingabe ausgegeben wird.

21
CMS

Eine referenziell transparente Funktion verhält sich wie eine mathematische Funktion. Bei gleichen Eingaben werden immer dieselben Ausgaben erzeugt. Dies bedeutet, dass der übergebene Zustand nicht geändert wird und dass die Funktion keinen eigenen Zustand hat.

13
Barry Kelly

Wenn Sie sich für die Etymologie interessieren (dh warum hat dieses Konzept diesen bestimmten Namen), werfen Sie einen Blick auf meinen Blogbeitrag zum Thema. Die Terminologie stammt vom Philosophen/Logiker Quine.

8
Andrew Birkett

Für diejenigen, die eine prägnante Erklärung benötigen, riskiere ich eine (aber lesen Sie die Offenbarung weiter unten).

Die referenzielle Transparenz in einer Programmiersprache fördert das gleichberechtigte Denken - je mehr referenzielle Transparenz Sie haben, desto einfacher ist das gleichberechtigte Denken. Z.B. mit einer (Pseudo) Funktionsdefinition,

f x = x + x,

die Leichtigkeit, mit der Sie f(foo) durch foo + foo im Geltungsbereich dieser Definition (sicher) ersetzen können, ohne zu viele Einschränkungen dafür zu haben, wo Sie diese Reduktion durchführen können, ist ein guter Hinweis darauf, wie viel referenziell ist Transparenz, die Ihre Programmiersprache hat.

Wenn zum Beispiel foo x ++ im Sinne der C-Programmierung wäre, könnten Sie diese Reduktion nicht sicher durchführen (dh wenn Sie diese Reduktion durchführen würden, würden Sie nicht mit demselben Programm enden, mit dem Sie begonnen haben).

In praktischen Programmiersprachen gibt es keine perfekte referenzielle Transparenz, aber funktionale Programmierer interessieren sich mehr als die meisten anderen (vgl. Haskell, wo dies ein zentrales Ziel ist).

(Vollständige Offenlegung: Ich bin ein funktionaler Programmierer. Bei der ersten Antwort sollten Sie diese Erklärung mit einem Salzkorn nehmen.)

7
chrisdornan
  1. Die Denotational-Semantik basiert auf der Modellierung von Sprachen, indem Domänen gebildet werden, die als bezeichnende Werte Werte dienen.
  2. Funktionsprogrammierer verwenden den Begriff value , um die Konvergenz einer Berechnung basierend auf den Umschreiberegeln der Sprache zu beschreiben, dh. seine operationelle Semantik.

In 1 werden zwei Sprachen in Frage gestellt: 

  • die modelliert wird, die Objektsprache
  • die modelliersprache, die metasprache 

In 2 können sie durch die Nähe des Objekts und die Metasprache verwirrt werden.

Als Sprach-Implementierer muss ich mich ständig an diese Unterscheidung erinnern. 

Also, Prof. Reddy, darf ich Sie so umschreiben :-)

Im Kontext der funktionalen Programmierung und der Semantik wird der Begriff referential Transparenz ist nicht referenziell transparent.

4
Anuradha

Die folgende Antwort, die ich hoffe, ergänzt und qualifiziert die umstrittenen 1. und 3. Antworten.

Lassen Sie uns zu, dass ein Ausdruck auf einige referent verweist. Es stellt sich jedoch die Frage, ob diese Referenten als Teil der Ausdrücke selbst isomorph codiert werden können und diese Ausdrücke als "Werte" bezeichnen. Beispielsweise sind Literalzahlenwerte eine Teilmenge der Menge von arithmetischen Ausdrücken, Wahrheitswerte sind eine Teilmenge der Menge von Booleschen Ausdrücken usw. Die Idee besteht darin, einen Ausdruck auf seinen Wert (sofern vorhanden) auszuwerten. Das Wort "value" kann sich also auf eine Bezeichnung oder auf ein unterschiedliches Element der Menge von Ausdrücken beziehen. Wenn jedoch zwischen dem referent und dem Wert ein Isomorphismus (ein Übergang) besteht, können wir sagen, dass sie dasselbe sind. (Das heißt, man muss darauf achten, die Referenten und den Isomorphismus zu definieren. Dies wird durch das Feld der Denotational-Semantik belegt.) Um die Antwort in der dritten Antwort zu nennen, wird der algebraische Datentyp .__ Definition data Nat = Zero | Suc Nat entspricht nicht wie erwartet der Menge der natürlichen Zahlen.)

Lassen Sie uns E[·] für einen Ausdruck mit einem Loch schreiben, das auch in manchen Vierteln bekannt ist als 'Kontext'. Zwei Kontextbeispiele für C-ähnliche Ausdrücke sind [·]+1 und [·]++.

Lassen Sie uns [[·]] für die Funktion schreiben, die einen Ausdruck (ohne Loch) Nimmt und dessen Bedeutung (referent, denotation usw.) in einem Bedeutungsgebenden Universum liefert. (Ich leihe Notationen aus dem Feld Der Bezeichnungssemantik.)

Lassen Sie uns die Definition von Quine etwas formal wie folgt anpassen: Ein Kontext E[·] ist referentiell transparent, wenn zwei beliebige Ausdrücke E1 und E2 (keine Löcher ) Gegeben sind, so dass [[E1]] = [[E2]] (dh die Ausdrücke bezeichnen/referenzieren). .same referent) dann ist es der Fall, dass [[E[E1]]] = [[E[E2]]] (dh das Ausfüllen von das Loch mit E1 oder E2 zu Ausdrücken führt, die dasselbe referent angeben).

Die Leibniz-Regel, Gleiches durch Gleiche zu ersetzen, wird normalerweise ausgedrückt als "Wenn E1 = E2 dann E[E1] = E[E2]", was besagt, dass E[·] eine Funktion ist. Eine Funktion .__ (oder auch ein Programm, das die Funktion berechnet) ist eine Zuordnung von einer Quelle zu einem Ziel, so dass höchstens ein Zielelement für jedes Quell-Element vorhanden ist. Nicht-deterministische Funktionen sind falsche Namen, sie sind entweder Relationen, Funktionen, die Mengen liefern, usw. Wenn in der Regel von Leibniz = Denotional ist, dann werden die doppelten Klammern einfach als gegeben betrachtet und Ein referenziell transparenter Kontext ist also eine Funktion. Und die Regel von Leibniz ist der Hauptbestandteil des Gleichstellungsdenkens. Daher ist das Gleichungsdenken eindeutig mit referenzieller Transparenz verbunden.

Obwohl [[·]] eine Funktion von Ausdrücken bis zu Bezeichnungen ist, könnte es eine Funktion von Ausdrücken bis zu 'Werten' sein, die als eingeschränkte Teilmenge von Ausdrücken verstanden werden, und [[·]] kann als Auswertung verstanden werden.

Wenn nun E1 ein Ausdruck ist und E2 ein Wert ist, haben wir das, was meiner Meinung nach unter den meisten Menschen zu verstehen ist, wenn Sie referenzielle Transparenz in Form von Ausdrücken, Werten und Bewertung definieren. Wie aus den ersten und dritten Antworten auf dieser Seite hervorgeht, handelt es sich hierbei jedoch um eine ungenaue Definition.

Das Problem bei Kontexten wie [·]++ ist nicht die Nebenwirkung, sondern der Wert ist in C nicht isomorph zu seiner Bedeutung definiert. Funktionen sind Nicht Werte (na ja, Zeiger auf Funktionen sind), während sie in funktionalen Programmiersprachen sind. Landin, Strachey und die Pioniere der Denotationssemantik waren in .__ ziemlich klug und nutzten funktionale Welten, um Bedeutung zu liefern.

Für imperative C-ähnliche Sprachen können wir (grob) Semantik für __.-Ausdrücke mit der Funktion [[·]] : Expression -> (State -> State x Value) bereitstellen.

Value ist eine Teilmenge von Expression. State enthält Paare (Bezeichner, Wert). Die semantische Funktion nimmt einen Ausdruck und liefert als Ihre Bedeutung eine Funktion aus dem aktuellen Zustand an das Paar mit dem aktualisierten Zustand und einem Wert. Zum Beispiel ist [[x]] die Funktion vom aktuellen Zustand bis zum Paar, dessen erste Komponente der aktuelle Zustand ist und dessen zweite Komponente der Wert von x ist. Im Gegensatz dazu ist [[x++]] die Funktion vom aktuellen -Zustand bis zu dem Paar, dessen erste Komponente ein Zustand ist, in dem der Wert .__ von x inkrementiert wird und dessen zweite Komponente genau dieser Wert ist. In diesem Sinn ist der Kontext [·]++ referenziell transparent, wenn er der oben angegebenen Definition von .__ genügt. 

Ich denke, dass funktionale Programmierer berechtigt sind, referenzielle Transparenz in Zu verwenden, in dem Sinn, dass sie [[·]] als Funktion von Ausdrücken bis Werten. Wiederherstellen. Funktionen sind erstklassige Werte und der Zustand kann auch ein Wert sein, kein Wert Bezeichnung. Die Zustandsmonade ist (zum Teil) ein sauberer Mechanismus zum Übergeben (oder Einfädeln) des Zustands.

3
user5998940

Man beachte, dass dieses Konzept von "Bedeutung" etwas ist, das im Kopf des Betrachters geschieht. Daher kann dieselbe "Referenz" für verschiedene Personen verschiedene Dinge bedeuten. So haben wir beispielsweise eine Wikipedia-Seite zur Begriffsklärung in Edinburgh.

Ein verwandtes Problem, das im Zusammenhang mit der Programmierung auftreten kann, könnte Polymorphismus sein.

Und vielleicht sollten wir einen Namen für den speziellen Fall des Polymorphismus (oder sogar des Castings) haben, wo die unterschiedlichen polymorphen Fälle für unsere Zwecke semantisch gleichwertig sind (im Gegensatz dazu, dass sie nur ähnlich sind. Zum Beispiel die Zahl 1 - die dargestellt werden könnte) mit einem ganzzahligen Typ oder einem komplexen Typ oder einem beliebigen aus einer Vielzahl anderer Typen - kann polymorph behandelt werden).

2
rdm

Ich fand die Definition von referentielle Transparenz in dem Buch "Struktur und Implementierung von Computerprogrammen" (das Wizard - Buch) nützlich, weil es durch eine Erklärung ergänzt wird, wie referenzielle Transparenz wird durch die Einführung der Zuweisungsoperation verletzt. Schauen Sie sich das folgende Dia-Deck an, das ich zum Thema gemacht habe: https://www.slideshare.net/pjschwarz/einleitung-zuweisung-invalidiert-das-substitution-modell-von-auswertung-und-violaten-referenztransparenz- wie erklärt-in-sicp-the-Wizard-Buch

0
Philip Schwarz

Referentielle Transparenz kann einfach ausgedrückt werden als:

  • Ein Ausdruck, der in jedem Kontext immer dasselbe Ergebnis liefert [1] ,
  • Wenn eine Funktion zweimal dieselben Parameter erhält, muss sie zweimal dasselbe Ergebnis liefern [2] .

Beispielsweise ist die Programmiersprache Haskell eine reine Funktionssprache. was bedeutet, dass es referenziell transparent ist.

0
Can