Beim Lesen von Peter Norvigs Python IAQ bin ich auf dieses Code-Snippet gestoßen:
%Vor%Ich habe das im Internet gesucht und dieser Code ist in verschiedenen Foren erschienen, aber es scheint, dass diejenigen, die dazu kommentiert haben, verstehen, wie es funktioniert.
Ich bin ziemlich neu in funktionalen Programmierkonzepten. Ich weiß, wenn der Test auf True
ausgewertet wird, wird delay(alternative)
ausgewählt. Aber wenn der Test wahr ist, wird das Ergebnis zurückgegeben. Das scheint mir kontraintuitiv zu sein.
Mal sehen:
_if(True)
wird aufgerufen und gibt sofort ein Lambda mit dem Parameter alternative
alternative
auf 1
und das result
lambda result
Lambda wird aufgerufen mit result
auf lambda: n * fact(n-1)
not not True
ergibt 1 (Dieses Beispiel stammt aus der Python 2.4-Ära!), die den zweiten Listeneintrag indiziert, nämlich delay(alternative)
alternative
wurde auf 1
früher delay(1)
wird aufgerufen, was lambda: 1
zurückgibt
lambda: 1
wird aufgerufen, es gibt 1
zurück. TL / DR: 1
ist alternative
.
Benannte Funktionen Version:
%Vor%Gehen Sie es rückwärts durch.
%Vor%Die erste Funktion reduziert sich auf [_if (100 & lt; = 1)] und wählt zwischen den zwei Funktionen [(1)] und [(Lambda: n * Tatsache (n-1))] aus. Wie bereits beschrieben, rufen True-Funktionen die 2. Funktionen auf, False die erste. Also wird die zweite Funktion aufgerufen und das Lambda wird wie folgt ausgewertet:
%Vor%Beachten Sie, dass die Verzögerungsfunktion in diesem Fall nichts bewirkt. Der ganze Prozess beginnt von neuem mit fact (99):
%Vor%Erneut ist der Funktionsaufruf _if True und löst den zweiten Funktionsaufruf aus, der dann eine weitere Tatsache aufruft (98) und so fort.
Der Stapel wird langsam aufgebaut:
%Vor%Der Sonderfall ist Fakt (1):
%Vor%seit _if jetzt False ist, wird die erste Funktion an delay übergeben, die sie in eine Funktion konvertiert und sie aufruft, 1 zurückgibt und dem Stack erlaubt, aufzulösen. Die Multiplikation erfolgt und das Ergebnis ist gegeben (100!).