Hatena::Groupsicp

yharaの日記

参考リンク
 | 

2007-05-03

[].6 21:02

制御構造を自分で定義できるか?の話。Schemeでは引数が先に評価されるので、

new-ifを呼び出す*前に*sqrt-iterが呼ばれてしまい無限ループになる。

試してみよう。(書籍内のコードhttp://mitpress.mit.edu/sicp/code/index.htmlコピペすると楽です)

1.6.scm

(define (square x) (* x x))

;(define (sqrt-iter guess x)
;  (if (good-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 (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.001))

(define (sqrt x)
  (sqrt-iter 1.0 x))

(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)))

この定義で√5を求めてみる。

yhara@meteor:~/src/sicp % rlwrap gosh
gosh> (load "./1.6.scm")
#t
gosh> (sqrt 5.0)
(帰ってこないのでCtrl-cを押す)
*** ERROR: unhandled signal 2 (SIGINT)
Stack Trace:
_______________________________________
  0  (* x x)
        At line 1 of "./1.6.scm"
  1  (square guess)
        At line 16 of "./1.6.scm"
  2  (abs (- (square guess) x))
        At line 16 of "./1.6.scm"
  3  (good-enough? guess x)
        At line 26 of "./1.6.scm"
 (中略)
 29  (sqrt-iter (improve guess x) x)
        At line 28 of "./1.6.scm"
... (more stack dump truncated)
gosh>

無限ループになったようだ。

Haskellだと遅延評価なのでmy-ifが定義できる。

Schemeでもマクロを使えばmy-ifが定義できる(マクロ引数マクロ展開前に評価されない)。

ChristianaChristiana2012/01/10 09:33That's more than snebsile! That's a great post!

sgiodkkfjgssgiodkkfjgs2012/01/10 19:14Gv8tkW <a href="http://cjqpfjauqswr.com/">cjqpfjauqswr</a>

ntfhyvcwntfhyvcw2012/01/12 22:54TKFix7 <a href="http://egvshzpudncy.com/">egvshzpudncy</a>

 |