読者です 読者をやめる 読者になる 読者になる

ochalog

Ruby と MediaWiki が好きな電子・情報系の学生のブログ。

SICP: Exercise 1.6

プログラミング Scheme SICP
(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause)))

という if のような手続きを定義して、

(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.001))
 
(define (average x y)
  (/ (+ x y) 2))
 
(define (improve guess x)
  (average guess (/ x guess)))
 
(define (sqrt-iter guess x)
  (new-if (good-enough? guess x)
    guess
    (sqrt-iter (improve guess x) x)))

とするとどうなるか、という問題。

p. 19 に (if <predicate> <consequent> <alternative>) の評価について、

  1. まず <predicate> を評価する。
  2. <predicate> が真の値なら、<consequent> を評価してその値を返す。
  3. そうでなければ <alternative> を評価してその値を返す。

とある。<predicate> が真の値ならば <alternative> は評価されないということが肝要。

new-if の方は特別形ではなく普通の手続きなので、predicate にかかわらず必ず else-clause も評価されてしまう。sqrt-iter の場合、それが sqrt-iter 自身であり再帰的に呼び出す形になっているので、たとえ good enough であったとしても計算が終わらなくなってしまう。これが答えだと思う。