Unterschied zwischen Bewertung normaler und anwendbarer Ordnung


9

Die Sprache, die ich lerne, ist Schema und ich arbeite an einer Übung, die Folgendes gibt:

(define (p) (p) )

(define (test x y) (if (= x 0)
                               0
                               y))

Dann wird die Frage gestellt, den Ausdruck zu bewerten: (Test 0 (p)) und das Verhalten zu kommentieren, das bei der Bewertung der normalen Reihenfolge und der anwendbaren Reihenfolge beobachtet werden würde.

Das sind meine Gedanken:

Bei normaler Reihenfolge wertet das Programm die Unterausdrücke aus, bevor es fortfährt:

So ( test 0 (p) )wird:

(test 0 p)
( if (= x 0) 0 p))

Ausgabe zurückgeben 0

Der einzige Unterschied in der Anwendungsreihenfolge besteht darin, dass das Programm wie folgt ausgeführt wird:

( test 0 (p) ) wird:

(test 0 (p))
( if (= x 0) 0 (p)))

Ausgabe zurückgeben 0

Somit (p)würde niemals ausgewertet, da es nicht benötigt wird.

Ist das richtig? Bitte lassen Sie es mich wissen, da ich fast keine Programmiererfahrung habe.


1
Ich empfand die Frage als allgemein genug, um die Behandlung hier zu rechtfertigen.
Babou

Antworten:


19

Welche Nachforschungen haben Sie angestellt, um diese Frage zu beantworten? Ich habe es einfach so eingesteckt, wie es in Google ist, und als zweite Antwort (die erste ist vielleicht so gut, ich habe sie nicht überprüft) einen Verweis auf einen Abschnitt einer Bibel zu Ihrem Thema erhalten: Hal Abelsons, Jerry Sussmans und Julie Sussmans Struktur und Interpretation von Computerprogrammen (MIT Press, 1984; ISBN 0-262-01077-1), auch bekannt als das Assistentenbuch. Der Verweis bezieht sich auf den Abschnitt " Normale Bestellung und anwendbare Bestellung ".

Es sagt aus:

Das Schema ist eine Sprache der anwendbaren Ordnung, dh, dass alle Argumente für Schema-Verfahren bewertet werden, wenn das Verfahren angewendet wird. Im Gegensatz dazu verzögern Sprachen normaler Ordnung die Auswertung von Prozedurargumenten, bis die tatsächlichen Argumentwerte benötigt werden.

und fügt hinzu, dass letzteres als faule Bewertung bezeichnet wird .

Sie haben also falsche Definitionen und nehmen eine für die andere:

  • Die anwendbare Reihenfolge wertet Unterausdrücke aus, wenn, dh kurz bevor das Verfahren angewendet wird.

  • Die normale Reihenfolge übergibt die Unterausdrücke unverändert ohne Auswertung und fährt mit der Auswertung nur fort, wenn der entsprechende formale Parameter tatsächlich selbst ausgewertet werden soll. (Es gibt eine weitere Wendung in Bezug auf Umweltprobleme ... aber das vergessen wir an dieser Stelle besser).

Darüber hinaus verstehen Sie den Anrufmechanismus, der zwei Dinge umfasst, nicht richtig:

  • den Parameterübergabemechanismus, der die ordnungsgemäße Verarbeitung der tatsächlichen Argumente für den Aufruf in Abhängigkeit von der Bewertungsregel umfasst;

  • das "Ersetzen" des Aufrufs der Funktion durch den Hauptteil der Funktion (ohne den Header).

Bei der Bewertung der anwendbaren Reihenfolge von ( test 0 (p) )sollten Sie zuerst die Argumentausdrücke auswerten. Das sind 0 und (p).

  • Die Bewertung eines wörtlichen Wertes 0ergibt diesen Wert.

  • Das zweite Argument ist jedoch ein Prozeduraufruf für eine aufgerufene Prozedur ohne Parameter p. Es hat keinen Parameter, so dass wir uns keine Sorgen um die Auswertungsreihenfolge machen müssen. Um die Bewertung fortzusetzen, müssen wir dann den Aufruf durch den Hauptteil der Prozedur ersetzen, die der Liste der Argumente folgt, und dann diesen Hauptteil bewerten. Das in pder Erklärung festgelegte Verfahren (define (p) (p) )ist (p)so, dass wir die Bewertung dessen behalten, was wir gerade zu bewerten versuchten. Mit anderen Worten, der Bewertungsprozess befindet sich in einer Schleife und wird nicht beendet.

... und Sie können den Aufruf der Funktion nie tatsächlich beenden test, da die Auswertung ihrer Argumente nicht beendet wird. Ihr Programm wird nicht beendet.

Dieses Risiko der Nichtbeendigung, selbst wenn das Schuldargument niemals im Aufruf verwendet wird, ist einer der Gründe für die Verwendung einer normalen Auftragsbewertung, die möglicherweise etwas schwieriger zu implementieren ist, aber möglicherweise bessere Beendeneigenschaften aufweist.

Bei der normalen Ordnungsbewertung berühren Sie die Argumentunterausdrücke nicht. Was Sie tun, ist, den Aufruf ( test 0 (p) )durch den Hauptteil der Funktion zu ersetzen test, dh (if (= x 0) 0 y)wo die Namen der (formalen) Argumente xund ydurch die entsprechenden tatsächlichen Argumente ersetzt werden 0und (p)(bis zur Umgebung oder Umbenennungsprobleme, die wichtig sind, aber die komplizieren würden Erklärung hier und sind der Hauptunterschied zwischen der ursprünglichen Lisp- und der Schemasprache).

Daher ersetzen Sie die Bewertung von ( test 0 (p) )durch die Bewertung von (if (= 0 0) 0 (p)).

Jetzt ist die Funktion ifeine primitive Funktion, die normalerweise immer ihr erstes Argument auswertet, aber ihre letzten beiden Argumente in normaler Reihenfolge auswertet und nur das nützliche auswertet, je nachdem, ob das erste als falsch oder wahr (tatsächlich NILoder #ffür falsch oder ein anderes) ausgewertet wird Wert für wahr , im Fall von Schema - wenn mein Gedächtnis mich nicht verfehlt). Da sich die (= 0 0)Bewertung als wahr herausstellt, wird die Bewertung des bedingten Betrags zur Bewertung des noch nicht bewerteten zweiten Arguments durchgeführt, was 0(außer im alten Fortran) nicht überraschend ist 0.

Tiefer Atemzug.


Ich denke , OP mit der Definition in Kapitel 1 wie verwirrt ist dies
SMA
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.