Wenn man so etwas wie diesen Wikipedia-Artikel über "reine Funktionen" liest, scheinen sie Today()
als Beispiel für eine unreine Funktion aufzulisten, aber es scheint mir ziemlich rein. Liegt es daran, dass es kein formales Eingabeargument gibt? Warum wird die aktuelle Uhrzeit nicht als "Eingabe für die Funktion" behandelt, wenn Sie dieselbe Eingabe vorgenommen haben, dh today()
zweimal zur selben Zeit ausgeführt haben oder die Zeit zurückgereist sind, um sie erneut auszuführen (möglicherweise eine Hypothese: )), wäre die Ausgabe zur gleichen Zeit. Today()
gibt dir niemals eine Zufallszahl. es gibt dir immer die Tageszeit.
Der Wikipedia-Artikel sagt, dass "unterschiedliche Zeiten unterschiedliche Ergebnisse liefern", aber das heißt, dass "für unterschiedliche Zeiten" x
sin(x)
unterschiedliche Verhältnisse ergeben. Und sin(x)
ist ihr Beispiel für eine reine Funktion.
quelle
Antworten:
Dies liegt daran, dass die Ausgabe von etwas abhängt, das keine Eingabe ist, nämlich der aktuellen Uhrzeit.
Weil Sie es nicht als Parameter übergeben haben. Wenn Sie es als Parameter übergeben, wird die Funktion bei Datumsangaben zu einer Identitätsfunktion, was ziemlich nutzlos ist. Der springende Punkt einer
Today()
Funktion ist, etwas auszugeben, das von einem externen und sich ständig ändernden Wert (Zeit) abhängt.Der Vorteil von reinen Funktionen ist, dass ihr Verhalten absolut reproduzierbar und deterministisch ist, was formale Beweise und strenge Garantien erleichtert. Sie machen immer das Gleiche.
Today()
ist so ziemlich das Gegenteil: es macht immer (unter Berücksichtigung der Zeitgranularität) etwas anderes.quelle
Today()
) liegtToday()
. DieToday()
Funktion könnte ein bisschen albern sein. Geeigneter könnte eineCount()
Funktion sein. Wenn die Anzahl der zu zählenden Elemente gleich ist,Count()
wird immer die gleiche Anzahl zurückgegeben, da dies jedoch außerhalb des Geltungsbereichs liegtCount()
, ist dies unrein.count()
auf den meisten Programmiersprachen ist definitiv rein. Es hat einen expliziten Eingabewert: die Sammlung, deren Anzahl Sie möchten. Lassen Sie sich nicht durch eine Syntax wie verwirrenmyCollection.count()
; das ist nur zucker fürcount(myCollection)
.sin(x)
gibt immer den gleichen Wert zurück, solange er gleichx
bleibt.Today()
kann im Laufe der Zeit unterschiedliche Ergebnisse liefern, da dies von Werten abhängt, die außerhalb Ihrer Kontrolle liegen . Wenn zum Beispiel etwas außerhalb der Kontrolle Ihres Programms das interne System ändert,$current_datetime
während Ihr Programm ausgeführt wird,Today()
ergeben sich plötzlich andere Ergebnisse.quelle
Today()
würde ein Anruf an einem Montag "Donnerstag" zurückgeben.Today () ist eine unreine Funktion, weil ihr Ergebnis von etwas abhängt, das Sie ihm nicht geben. Insbesondere die aktuelle Systemzeit. Daher ist das Ergebnis nicht deterministisch, wenn es nur auf den beim Aufruf bereitgestellten Eingaben basiert.
Eine reine Funktion wäre
int Add(int a, int b) {return a + b;}
. Die Funktion arbeitet ausschließlich mit dem, was sie enthält, und verwendet keine anderen externen Zustandsdaten. Das natürliche Ergebnis davon ist, dass SieAdd(2,2)
von jetzt an bis zum Ende der Zeit 4 bekommen können. Da die Funktion keinen externen Status ändert (es gibt keine "Nebenwirkungen"), ändert das Hinzufügen von 2 und 2 von jetzt an bis zum Ende der Zeit nichts anderes im System, es sei denn, Sie ändern dies Weisen Sie das Ergebnis der Funktion einer Variablen zu, oder verwenden Sie den Wert auf andere Weise, um den Status zu aktualisieren (was keine von der Funktion selbst ausgeführte Operation ist). Praktisch alle klassischen mathematischen Operationen sind reine Funktionen und können als solche implementiert werden.Auf der anderen Seite kann Today () denselben Wert erzeugen, wenn es zweimal hintereinander aufgerufen wird, aber nicht, wenn es mehrere Tage lang wiederholt aufgerufen wird. Dies liegt daran, dass es von externen Statusdaten abhängt, die Sie nicht als Parameter für die Funktion angegeben haben. Infolgedessen ist es innerhalb der Programmgrenzen unmöglich, das Ergebnis der Today () - Funktion zu steuern. Es wird an einem bestimmten Tag einen bestimmten Wert und an keinem anderen Tag einen bestimmten Wert erzeugen, es sei denn, Sie ändern die Systemuhr des Computers, auf dem es ausgeführt wird (eine Änderung, die im Allgemeinen außerhalb der Programmgrenzen auftritt).
Eine unreine Funktion ist nicht unbedingt eine schlechte Sache; Selbst in funktionalen Sprachen sind unreine Funktionen erforderlich, um mit etwas außerhalb der Programmgrenzen zu interagieren, z. B. mit Datenspeichern, Kommunikations-Pipelines, Benutzeroberflächenanzeigen, Peripheriegeräten usw. Ein Programm, das keine dieser Funktionen ausführt, ist ein Programm das ist in seiner Nützlichkeit scharf begrenzt; Ich würde sogar so weit gehen, ein solches Programm als trivial zu bezeichnen, da es, ohne irgendwelche Mittel, um Eingaben zu akzeptieren oder um Sie über seine Ausgabe zu informieren, genauso gut nichts tun könnte. In funktionalen Sprachen geschriebene Programme können nur die von der Laufzeit bereitgestellten Eingaben haben und eine Ausgabe erzeugen, die der Laufzeit ohne explizit definierte unreine Methoden gemeldet wird. Dies liegt jedoch daran, dass die Laufzeit all diese unreinen Details der Arbeit in einem unvollkommenen Computersystem abstrahiert.
Es ist einfach eine sehr gute Sache zu wissen, welche der von Ihnen verwendeten Funktionen rein sind und welche nicht, damit Sie gute Entscheidungen darüber treffen können, wie sie verwendet werden. Unreine Funktionen können sich nur bei Kenntnis der Verwendung unvorhersehbar verhalten, weil sie Dinge tun oder von Dingen abhängig sind, die aus ihrer Verwendung nicht ersichtlich sind. Weitere Kenntnisse über den Zweck der Funktion und damit darüber, was sie von einem externen Zustand benötigt oder für einen externen Zustand tut, sind erforderlich, um ein System, das sie verwendet, in einen konsistenten Zustand zu versetzen und damit ein deterministisches Ergebnis zu erwarten.
quelle
Es scheint ziemlich offensichtlich, dass diese Funktion den ersten Reinheitstest, der zu Beginn dieser Seite angegeben wurde, nicht besteht:
Beachten Sie, dass es nur eine mögliche Menge von Argumentwerten gibt - die leere Menge, da keine Argumente akzeptiert werden. Und diese Funktion kann und kann unterschiedliche Ergebnisse für den gleichen 'Argumentwert ( die gleichen Argumentwerte)' zurückgeben.
Darüber hinaus ist die Funktion Ergebniswert ist , hängt von „versteckt ... Zustand, wie geht die Programmausführung ändern können“. Also noch ein Misserfolg.
quelle
() => 1
wäre eine reine Funktion, da sie immer 1.Today()
"Montag" oder "Dienstag" oder fast jeden anderen Wert zurückgeben kann.Eine andere Sichtweise ist, dass reine Funktionen nicht vom Zustand abhängen. Die Welt wird typischerweise als Staat betrachtet. Sie müssen den Zustand der Realität kennen, um zu wissen, welcher Tag heute ist.
Sie müssen jedoch nichts Besonderes über den Zustand der Welt wissen, um zu wissen, was
sin(x)
ist. Und jeder Aufruf ansin(x)
für eine gegebenex
wird den gleichen Wert zurückgeben.quelle
Date(timestamp)
wäre eine reine funktion. Wegen seiner Idempotenz. Und weil es keine Nebenwirkungen geben würde.Today()
Das Ergebnis kann variieren, je nachdem, wann Sie es aufrufen. Das macht es unrein. Es ist nicht idempotent. Es hat zwar keine Nebenwirkungen, aber das macht es nicht rein.quelle
Hier ist ein kleiner Pseudocode, an den ich denke, wenn ich über reine Funktionen spreche
Wenn das auf unbestimmte Zeit läuft und das Assert niemals auslösen kann, ist es eine reine Funktion. Mehr so, wenn Sie eine Funktion haben, die Argumente verwendet, dann eine kleine Änderung ....
Wenn Sie dies nach jeder Variablenzuweisung in Ihrer App verwenden können und die Ergebnisse in Ihrer App nicht geändert werden und die Behauptung niemals fehlschlagen kann, ist dies eine reine Funktion.
quelle
Erstens gibt es keine Funktion ohne Argument (oder ein Array ohne Indizes oder eine Map ohne Schlüssel). Es ist das definierende Merkmal einer Funktion, einen oder mehrere Argumentwerte einem anderen Wert zuzuordnen.
Also
today
ist entweder gar keine Funktion, also keine reine Funktion. Oder wir interpretieren die Syntaxein bisschen so, dass es bedeutet
In Haskell wäre dies beispielsweise gültig:
weil es einen Typ () mit einem einzelnen Wert () gibt.
Die Frage ist nur, wie
today
man den Wochentag berechnen kann , wenn es nur () hat. Es ist einfach nicht möglich, ohne den Systemtimer direkt oder über unreine Helferfunktionen auszulesen.Der Systemtimer ist ein hervorragendes Beispiel für den globalen Zustand.
quelle
Das Problem dabei
today()
ist, dass es zu einem anderen Ergebnis kommen kann, wenn es in einer Funktion zweimal oder öfter aufgerufen wird.Hier ist ein Codebeispiel, das einen Fehler verursachen könnte.
Dies ist im obigen Beispiel möglich. Dass die zweite
if
Anweisung nicht ausgeführt wird. Auch wenn es der erste tat. Eine Ressource in einem schlechten Zustand belassen.quelle
Um eine reine Funktion zu sein, müssen dieselben Parameter jedes Mal dasselbe Ergebnis liefern.
Jedes Mal
Today()
, wenn wir anrufen , geben wir die gleichen Parameter an (keine) und erhalten dennoch nicht unbedingt das gleiche Ergebnis (Montag, Dienstag usw.).quelle