Die "normale" Art zu formulieren, was eine reine Funktion ist, ist die referenzielle Transparenz . Eine Funktion ist rein, wenn sie referenziell transparent ist .
Referentielle Transparenz bedeutet ungefähr, dass Sie den Aufruf der Funktion an jeder Stelle im Programm durch ihren Rückgabewert ersetzen können oder umgekehrt, ohne die Bedeutung des Programms zu ändern.
Wenn beispielsweise printf
Cs referenziell transparent wären , sollten diese beiden Programme dieselbe Bedeutung haben:
printf("Hello");
und
5;
und alle folgenden Programme sollten dieselbe Bedeutung haben:
5 + 5;
printf("Hello") + 5;
printf("Hello") + printf("Hello");
Weil printf
die Anzahl der geschriebenen Zeichen zurückgibt, in diesem Fall 5.
Bei void
Funktionen wird es noch deutlicher . Wenn ich eine Funktion habe void foo
, dann
foo(bar, baz, quux);
sollte das gleiche sein wie
;
Das heißt, da foo
nichts zurückgegeben wird, sollte ich es durch nichts ersetzen können, ohne die Bedeutung des Programms zu ändern.
Es ist also klar, dass weder printf
noch foo
referenziell transparent sind und somit keiner von ihnen rein ist. Tatsächlich kann eine void
Funktion niemals referenziell transparent sein, es sei denn, es handelt sich um ein No-Op.
Ich finde diese Definition viel einfacher zu handhaben als die, die Sie gegeben haben. Sie können es auch in jeder gewünschten Granularität anwenden: Sie können es auf einzelne Ausdrücke, Funktionen und ganze Programme anwenden. So können Sie beispielsweise über eine Funktion wie diese sprechen:
func fib(n):
return memo[n] if memo.has_key?(n)
return 1 if n <= 1
return memo[n] = fib(n-1) + fib(n-2)
Wir können die Ausdrücke analysieren, aus denen die Funktion besteht, und leicht den Schluss ziehen, dass sie nicht referenziell transparent und daher nicht rein sind, da sie eine veränderbare Datenstruktur verwenden, nämlich das memo
Array. Wir können jedoch auf die Funktion auch einen Blick und sehen , dass es ist referentiell transparent und somit rein. Dies wird manchmal als äußere Reinheit bezeichnet , dh eine Funktion, die der Außenwelt rein erscheint, aber intern unrein implementiert wird.
Solche Funktionen sind immer noch nützlich, da die Verunreinigung zwar alles um sie herum infiziert, die externe reine Schnittstelle jedoch eine Art "Reinheitsbarriere" bildet, bei der die Verunreinigung nur die drei Zeilen der Funktion infiziert, aber nicht in den Rest des Programms gelangt . Diese drei Zeilen sind viel einfacher auf Korrektheit zu analysieren als das gesamte Programm.