Ist das Folgende eine reine Funktion?
function test(min,max) {
return Math.random() * (max - min) + min;
}
Mein Verständnis ist, dass eine reine Funktion diesen Bedingungen folgt:
- Es gibt einen Wert zurück, der aus den Parametern berechnet wurde
- Es macht keine andere Arbeit als die Berechnung des Rückgabewerts
Wenn diese Definition korrekt ist, ist meine Funktion eine reine Funktion? Oder ist mein Verständnis dessen, was eine reine Funktion definiert, falsch?
javascript
function
pure-function
Kiwi Rupela
quelle
quelle
Math.random()
was den Status des RNG ändert.test(a,b)
immer das gleiche Objekt zurückRandom(a,b)
(das unterschiedliche konkrete Zahlen darstellen kann)? Wenn SieRandom
symbolisch bleiben , ist es im klassischen Sinne rein, wenn Sie es früh bewerten und Zahlen eingeben, vielleicht als eine Art Optimierung, behält die Funktion immer noch eine gewisse "Reinheit".Antworten:
Nein, ist es nicht. Bei gleicher Eingabe gibt diese Funktion unterschiedliche Werte zurück. Und dann können Sie keine 'Tabelle' erstellen, die die Eingabe und die Ausgaben abbildet.
Aus dem Wikipedia-Artikel für Pure function :
Eine andere Sache ist, dass eine reine Funktion durch eine Tabelle ersetzt werden kann, die die Zuordnung von Eingabe und Ausgabe darstellt, wie in diesem Thread erläutert .
Wenn Sie diese Funktion umschreiben und in eine reine Funktion ändern möchten, sollten Sie den Zufallswert auch als Argument übergeben
und nenne es dann so (Beispiel mit 2 und 5 als min und max):
quelle
Math.random
?Math.random
Ausgabe); Damit es rein ist, müssten Sie den aktuellen RNG-Status irgendwie speichern, neu säen, aufrufenMath.random
und auf den vorherigen Status zurücksetzen .Die einfache Antwort auf Ihre Frage lautet, dass sie
Math.random()
gegen Regel 2 verstößt.Viele andere Antworten hier haben darauf hingewiesen, dass das Vorhandensein von
Math.random()
bedeutet, dass diese Funktion nicht rein ist. Aber ich denke, es lohnt sich zu sagen, warumMath.random()
Taints-Funktionen es verwenden.Math.random()
Beginnt wie alle Pseudozufallszahlengeneratoren mit einem "Startwert". Dieser Wert wird dann als Ausgangspunkt für eine Kette von Bitmanipulationen auf niedriger Ebene oder für andere Operationen verwendet, die zu einer unvorhersehbaren (aber nicht wirklich zufälligen ) Ausgabe führen.In JavaScript ist der Prozess implementierungsabhängig, und im Gegensatz zu vielen anderen Sprachen bietet JavaScript keine Möglichkeit, den Startwert auszuwählen :
Deshalb ist diese Funktion nicht rein: JavaScript verwendet im Wesentlichen einen impliziten Funktionsparameter, über den Sie keine Kontrolle haben. Es liest diesen Parameter aus Daten, die an anderer Stelle berechnet und gespeichert wurden, und verstößt daher gegen Regel 2 in Ihrer Definition.
Wenn Sie dies zu einer reinen Funktion machen möchten, können Sie einen der hier beschriebenen alternativen Zufallszahlengeneratoren verwenden . Nennen Sie diesen Generator
seedable_random
. Es nimmt einen Parameter (den Startwert) und gibt eine "Zufallszahl" zurück. Natürlich ist diese Zahl überhaupt nicht zufällig; es wird eindeutig durch den Samen bestimmt. Deshalb ist dies eine reine Funktion. Die Ausgabe vonseedable_random
ist nur "zufällig" in dem Sinne, dass es schwierig ist, die Ausgabe basierend auf der Eingabe vorherzusagen.Die reine Version dieser Funktion müsste drei Parameter annehmen :
Für jedes gegebene Dreifach von
(min, max, seed)
Parametern wird immer das gleiche Ergebnis zurückgegeben.Beachten Sie, dass Sie einen Weg finden müssen, um den Startwert zufällig
seedable_random
zu bestimmen , wenn die Ausgabe von wirklich zufällig sein soll! Und jede Strategie, die Sie verwendet haben, wäre unweigerlich nicht rein, da Sie Informationen aus einer Quelle außerhalb Ihrer Funktion sammeln müssten. Wie mtraceur und jpmc26 mich erinnern, umfasst dies alle physikalischen Ansätze: Hardware-Zufallszahlengeneratoren , Webcams mit Objektivdeckeln , atmosphärische Geräuschkollektoren - sogar Lavalampen . All dies beinhaltet die Verwendung von Daten, die außerhalb der Funktion berechnet und gespeichert wurden.quelle
Math.random
kein PRNG verwendet würde, sondern stattdessen ein Hardware-RNG implementiert würde? Das Hardware-RNG hat nicht wirklich einen Zustand im normalen Sinne, aber es erzeugt zufällige Werte (und daher ist die Funktionsausgabe unabhängig von der Eingabe immer noch unterschiedlich), oder?Eine reine Funktion ist eine Funktion, bei der der Rückgabewert nur durch seine Eingabewerte ohne beobachtbare Nebenwirkungen bestimmt wird
Mit Math.random bestimmen Sie den Wert durch etwas anderes als Eingabewerte. Es ist keine reine Funktion.
Quelle
quelle
Nein, es ist keine reine Funktion, da ihre Ausgabe nicht nur von der bereitgestellten Eingabe abhängt (Math.random () kann einen beliebigen Wert ausgeben), während reine Funktionen immer denselben Wert für dieselben Eingaben ausgeben sollten.
Wenn eine Funktion rein ist, können Sie sicher mehrere Anrufe mit denselben Eingaben optimieren und nur das Ergebnis eines früheren Anrufs wiederverwenden.
PS Zumindest für mich und für viele andere hat Redux den Begriff reine Funktion populär gemacht. Direkt aus den Redux-Dokumenten :
quelle
Aus mathematischer Sicht ist Ihre Unterschrift nicht
aber
wo das
environment
in der Lage ist, Ergebnisse zu liefernMath.random()
. Wenn Sie den Zufallswert tatsächlich generieren, wird die Umgebung als Nebeneffekt mutiert, sodass Sie auch eine neue Umgebung zurückgeben, die nicht der ersten entspricht!Mit anderen Worten, wenn Sie irgendeine Art von Eingabe benötigen, die nicht aus anfänglichen Argumenten stammt (die
<number, number>
Teil) stammt, müssen Sie über eine Ausführungsumgebung verfügen (die in diesem Beispiel den Status für bereitstelltMath
). Gleiches gilt für andere Dinge, die in anderen Antworten erwähnt werden, wie E / A oder ähnliches.Als Analogie können Sie auch feststellen, dass objektorientierte Programmierung so dargestellt werden kann - wenn wir sagen, z
dann benutzen wir eigentlich
Das aufgerufene Objekt ist Teil der Umgebung. Und warum der
SomeClass
Teil des Ergebnisses? Weil sich auchsomething
der Zustand hätte ändern können!quelle
test: <environment, number, number> -> <environment, number>
sollte es seina.F(b, c)
kann als syntaktischer Zucker fürF(a, b, c)
mit einer speziellen Regel angesehen werden, um überladene DefinitionenF
basierend auf dem Typ von zu versendena
(so repräsentiert Python es tatsächlich). Ista
aber in beiden Notationen immer noch explizit, während die Umgebung in einer nicht reinen Funktion im Quellcode nie erwähnt wird.Reine Funktionen geben immer den gleichen Wert für den gleichen Eingang zurück. Reine Funktionen sind vorhersehbar und referenziell transparent, was bedeutet, dass wir den Funktionsaufruf durch die zurückgegebene Ausgabe ersetzen können und die Funktionsweise des Programms nicht verändert wird.
https://github.com/MostlyAdequate/mostly-adequate-guide/blob/master/ch3.md
quelle
Zusätzlich zu den anderen Antworten, die korrekt darauf hinweisen, dass diese Funktion nicht deterministisch ist, hat sie auch einen Nebeneffekt: Sie führt dazu, dass zukünftige Anrufe
math.random()
eine andere Antwort zurückgeben. Und ein Zufallszahlengenerator, der diese Eigenschaft nicht besitzt, führt im Allgemeinen eine Art E / A aus, z. B. zum Lesen von einem vom Betriebssystem bereitgestellten Zufallsgerät. Beides ist für eine reine Funktion verboten.quelle
Nein, ist es nicht. Sie können das Ergebnis überhaupt nicht herausfinden, daher kann dieser Code nicht getestet werden. Um diesen Code testbar zu machen, müssen Sie die Komponente extrahieren, die die Zufallszahl generiert:
Jetzt können Sie den Generator verspotten und Ihren Code richtig testen:
Und in Ihrem "Produktions" -Code:
quelle
util.Random
, die Sie zu Beginn eines Testlaufs festlegen können, um altes Verhalten zu wiederholen, oder für einen neuen (aber wiederholbaren) Lauf. Bei Multithreading können Sie dies möglicherweise im Hauptthread tun undRandom
damit wiederholbare threadlokaleRandom
s setzen. Soweit ich es verstehe,test(int,int,Random)
wird es jedoch nicht als rein angesehen, da es den Zustand desRandom
.Würden Sie mit folgendem in Ordnung sein:
gleichwertig sein mit
?
Sie sehen, die Definition von pure ist eine Funktion, deren Ausgabe sich nur durch ihre Eingaben ändert. Wenn wir sagen, dass JavaScript eine Möglichkeit hat, eine Funktion rein zu kennzeichnen und dies zu nutzen, kann der Optimierer den ersten Ausdruck als zweiten umschreiben.
Ich habe praktische Erfahrung damit. SQL Server erlaubt
getdate()
undnewid()
in "reinen" Funktionen und der Optimierer würde Aufrufe nach Belieben deduplizieren. Manchmal tat dies etwas Dummes.quelle