その質問に答えるためにどのような研究をしましたか?私はそれをグーグルでそのままプラグインし、2番目の回答として取得しました(最初の回答は良いかもしれませんが、チェックしませんでした)トピックに関する聖書のセクションへの参照:Hal Abelson、Jerry Sussman、およびJulie Sussmanの構造コンピュータプログラムの解釈(MIT Press、1984; ISBN 0-262-01077-1)、別名ウィザードブック。参照先は、「通常の順序と適用される順序」のセクションです。
それは述べています:
Schemeは適用順序言語です。つまり、Schemeプロシージャへのすべての引数は、プロシージャが適用されるときに評価されます。対照的に、通常の順序の言語では、実際の引数の値が必要になるまで、プロシージャの引数の評価が遅れます。
後者は遅延評価と呼ばれていると付け加えます。
だからあなたはあなたの定義を間違っており、他のもののために一つを取る:
さらに、次の2つを含む呼び出しメカニズムを適切に理解していません。
以下の場合、応用的順評価の( test 0 (p) )
、あなたは、最初の引数のsubxpressionsを評価することになっています。これらは0
および(p)
です。
のようなリテラル値の評価は、0
その値をもたらします。
ただし、2番目の引数は、と呼ばれるパラメータなしのプロシージャへのプロシージャコールp
です。パラメータがないので、評価の順番を気にする必要はありません。次に、評価を進めるために、呼び出しを引数のリストに続くプロシージャの本体に置き換え、その本体を評価する必要があります。p
宣言(define (p) (p) )
で定義されているように、手続きの本体は(p)
なので、評価しようとしていたものの評価が残ります。つまり、評価プロセスはループに巻き込まれ、終了しません。
...そしてtest
、その引数の評価が終了しないため、実際に関数の呼び出しを終了することはできません。プログラムは終了しません。
有罪の引数が呼び出しで使用されない場合でも、この非終了のリスクは、代わりに通常の順序評価を使用する理由の1つです。これは実装が少し難しいかもしれませんが、終了プロパティが優れている場合があります。
下では、通常の順序評価は、引数のサブ表現を触れないでください。あなたがやっていることは呼び出しを置き換えるある( test 0 (p) )
関数の本体でtest
、すなわち(if (= x 0) 0 y)
(正式な)引数の名前、x
およびはy
、対応する実引数に置き換えられます0
と(p)
、(環境まで、または名前変更の問題が重要であることが、複雑になりますここでの説明、そしてオリジナルのLispとScheme言語の主な違いです)。
したがって、あなたはの評価を置き換える( test 0 (p) )
の評価によって(if (= 0 0) 0 (p))
。
今、この関数はif
通常、常にその最初の引数を評価する原始関数であるが、最初に評価されるかどうかに応じて、唯一の有用な1評価、通常のために、その最後の2つの引数を評価し、偽または真(実際にNIL
または#f
のために
虚偽の、または他のいくつかのSchemeの場合はtrueの値-私の記憶が失敗しない場合)。はtrueと評価(= 0 0)
されるため、条件付きの量を評価することで、まだ評価されていない2番目の引数を評価します。0
0
深呼吸。