2017-11-07 29 views
2

Dr. Racket-Benutzer.Reihenfolge der Auswertung von Lambda-Ausdrücken in Schema

Hier sind zwei Ausdrücke:

((lambda (x) (+ x 1)) 3)

((lambda (x) (+ x 1) 2) 3)

Die erste ist eine Lambda-Ausdruck, der einen Eingang nimmt und erhöht sie um 1 dauert es also 3 als Operanden und Marken (lambda (3) (3 + 1), die

Die gleich 4 ist Der zweite ist mir seither sehr zweideutig es bewertet 2 und ich kann die Reihenfolge seiner Auswertung nicht verstehen. Ich weiß, dass es etwas mit den Klammern zu tun hat, die die Reihenfolge ändern, aber ich kann nicht verstehen, wie. Offensichtlich summiert es nicht einmal "die 1" und "das x" nur aus irgendeinem Grund, 2 als die Ausgabe produzierend. Ich vermisse ein grundlegendes Verständnis der Bewertung. Danke im Voraus!

+0

Verwenden Sie den algebraischen Stepper (den Fuß) in DrRacket, um diese Frage zu beantworten. Mit dem Stepper können Sie die Auswertung von Ausdrücken in einem Schritt durchführen (und auch rückwärts gehen!) – soegaard

Antwort

6

Wie in Racket docs erklärte:

Eine Funktionsdefinition können mehrere Ausdrücke für die körpereigene Funktion umfassen. In diesem Fall wird nur der Wert des letzten Ausdrucks zurückgegeben, wenn die Funktion aufgerufen wird. Die anderen Ausdrücke werden nur für einige Nebeneffekte wie Drucken ausgewertet.

Zum Beispiel:

(define (f x) 
    (+ 1 1)    ;; evaluates to 2, but not returned  
    (= 3 4)    ;; evaluates to false, but not returned 
    0     ;; evaluates to 0, but not returned 
    1000     ;; evaluates to 1000, but not returned 
    pi     ;; evaluates to pi, but not returned 
    "I am a string")  ;; last expression; evaluates and returns "I am a string" 

und

(f 10) 
=> "I am a string" 
(f 'okay) 
=> "I am a string" 
(f pi) 
=> "I am a string" 

Das gleiche ist bei Ihrem letzten Lambda passiert, wobei:

((lambda (x) (+ x 1) 2) 3) 
=> ((lambda() (+ 3 1) 2)) 
=> ((lambda() 4 2)) ;; last expression is 2, so output 2 
=> 2 
1

Der Körper aller abgeleiteten Formen von lambda wird von links nach rechts in der Reihenfolge ausgewertet wie in einer begin.

((lambda (x) 
    (+ x 1) ; not in tail position. no effect so it's dead code 
    2)  ; the evaluation of 2 will be the result every time 
3) ; argument, only used by dead code. 

Es macht tatsächlich die Summe erzeugen, werfen Sie es dann bewerten weg: Alle außer dem letzten Ausdruck sind nur für den Nebeneffekt, während das Ergebnis des letzten Ausdrucks wird das Ergebnis Ihrer Funktion ausgewertet letzter Ausdruck. Nur für den toten Code wird im Winter warm gehalten. Ein Beispiel für eine sinnvollere Verwendung von mehr Ausdrücken im Körper:

Und da dies Bewertungsreihenfolge erwähnt. Während Argumente für Funktionen in #lang racket streng in allen Scheme-Berichten wie #!r6rs von links nach rechts ausgewertet werden, kann eine Implementierung (wie Racket) eine beliebige Reihenfolge wählen. z.B.

((lambda (a b c) (display "d")) 
(display "a") 
(display "b") 
(display "c") 

Während der obige Code druckt immer „ABCD“ in #lang racket es ist nur eine von 6 möglichen Ergebnisse in Schema, da Sie nicht wissen, was die Argumente bestellen werden wird zuerst, mittlere und letzte und der Druck bewertet passieren in der Reihenfolge der Auswertung. Ich weiß, dass Schläger natürlich ihren Schema-Code von links nach rechts auswertet, während Ikarus das Gegenteil tut.

Verwandte Themen