let
-フォームは内部に複数の式を含むことができます:
(let ((x 4))
x
(+ x 1))
戻ります5
。
この式はどのように評価されますか?
let
-フォームは内部に複数の式を含むことができます:
(let ((x 4))
x
(+ x 1))
戻ります5
。
この式はどのように評価されますか?
これは Implicit と呼ばれbegin
ます。つまり、コードは次のように記述されているかのように評価されます。
(let ((x 4)) (begin x (+ x 1)))
念のため、用語を明確にしましょう。フォームには、バインディングとボディのlet
2 つの部分があります。
(let (<zero or more bindings>)
<one or more body expressions>)
バインディングの形式(<variable> <expression>)
は で、本体は一連の式です。Alet
は次のように評価されます。
あなたが説明している状況は、let
式だけでなく、Schemeのいくつかの部分で発生します。以下では ...
let
式の変数バインディングのリストの後lambda
式内のパラメーターのリストの後(したがって、プロシージャー定義内のパラメーターのリストの後)cond
式の各句の後...式のリストを書くことができます。暗黙的に、これらの式は特別なフォームで囲まれていますbegin
。評価の順序は左から右で、すべての式が順番に評価されますが、返される値は最後の式の値です。
たとえば、次の式は次のとおりです。
(cond ((= 1 1) 1 2 3))
と同等です:
(cond ((= 1 1) (begin 1 2 3)))
どちらの場合も、戻り値はです3
。これは、リストの最後の式の値だからです。
最初に、用語について説明します。変数バインディングの後の式はまとめて本体と呼ばれ、本体内の各式は本体式です。元:
(let ((variable-1 value-1)
(variable-2 value-2))
body-expression-1
body-expression-2)
本体の表現をbegin
--で囲んで(let ((x 2)) x (+ x 1))
いるのは と同じ(let ((x 2)) (begin x (+ x 1)))
です。
の各ボディ式begin
が評価され、最終的な式の戻り値がボディ全体の戻り値として使用されます。例:(begin (+ x 1) (+ x 2))
を評価(+ x 1)
し(+ x 2)
、評価の結果を返し(+ x 2)
ます。
のすべての本体式にbegin
副作用がない場合、プログラムの実行時の動作を変更することなく、最後の本体式を除くすべてを削除できます。ここでの唯一の例外は、予備のボディ式の 1 つが実行に時間がかかる/戻らない/エラーが発生する場合です。ボディ式を削除すると、プログラムの実行時の動作が変更され、問題が解消されます。
ただし、副作用のある関数を使用する場合は、副作用のために 1 つ以上の関数を呼び出してから値を返す機能が役立ちます。