計算機プログラムの構造と解釈
- 1.5
この前微妙な感じで終わってしまった。
自分でも良くわからなかったので、何とか納得できる形に説明してみる。
(define (p) (p)) (define (test x y) (if (= x 0) 0 y)) (test 0 (p)) ;;普通にMzSchemeで実行すると無限ループになった。
作用的順序と正規順序について復習
作用的順序評価では、関数を実行する時点で、値が被演算子が評価され値が呼ばれる。
よって、
(test 0 (p))
の時点で(p)を求めようとし、再帰の無限ループに入ってしまう。
一方、正規順序評価では、必要になるまで実際の値を求めようとはしない。
また、ifはスペシャルフォームなので、必要な引数に対してしか評価を実行しない。
(test 0 (p));;この時点では下に流れる。 (if (= 0 0) 0 (p));;ifの結果では、初めの「0」が呼び出される。 ;;ifは真になる条件以外の計算を省くため、(p)が実際呼び出されることはない。
こんな感じだろうか?
- 1.6
上と同じ感じに1.6もとける。
(define (new-if predicate then-clause else-clause) (cond (predicate then-clause) (else else-clause))) (define (sqrt-iter guess x) (new-if (good-enough? guess x) guess (sqrt-iter (improve guess x) x))) ;;普通にMzSchemeで実行すると無限ループになった。
上と同じで、defineで関数として定義したため、被演算子は宣言時点で評価されてしまう。
この例でいうと、
(sqrt-iter (improve guess x) x)))
の部分が再帰となっており、宣言時点で評価されてしまうため、無限ループに入った。
その点、ifはスペシャルフォームのため、評価は行われない。
今日はつかれたのでここまで。