SICPラン②(p22~ 1.1.7. 例: ニュートン法による平方根)

今まで出てきた「手続き」というのは、数学の関数によく似ている。しかしそれらには決定的に異なることがある。「手続き」では物事をどのようにして行うのかについて述べており、関数では物事の性質を述べているという違いである。(命令的知識と宣言的知識というらしい)
例として、平方根の関数の定義は
 \sqrt{x}=y\geq0 かつ  y^2 = x であるような  y
とされている。これは、平方根の性質を述べているだけでじゃあ具体的にどのように導出するのか、ということを「手続き」という。
そこで、ニュートン法による近似値導出をおこなう。これが手続き。

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

Ex 1.6: ifを特殊形式ではなく、condを使って新たにnew-ifを定義した場合の挙動の説明

(define (square x)
  (* x x))
(define (new-if predicate then-clause else-clause)
	(cond (predicate then-clause)
		  (else else-clause)))
(define (sqrt-iter guess x)
  (new-if(godd-enough? guess x)
     guess
     (sqrt-iter (improve guess x) x)))
(define (improve guess x)
  (average guess (/ x guess)))
(define (average x y)
  (/ (+ x y) 2))
(define (godd-enough? guess x)
  (< (abs (-(square guess) x))0.001))
(define (sqrt x)
  (sqrt-iter 1.0 x))

この時、処理が終わらない。特殊形式としてのifは、述語式が真のときに一つ目の引数を評価し、偽の場合にのみ二つ目の引数を評価する。しかし手続きとして定義されたnew-ifはすべての引数を最初に評価するので、sqrt-iterが評価され無限ループになる。