#ladiescpp の主催してる オンラインSICP読書女子会 2 - connpassのまとめです〜。
まちがっているところがあればどんどんコメントください(`・ω・´)ゞ
次回の参加は オンラインSICP読書女子会 #3 (1.2.1~1.2.2) - connpass から!
参加者のブログ
オンラインSICP読書女子会 #2 (1.1.7~1.1.8) — miumixu's tech blog
1.1.7
ニュートン法による平方根のお話。
sqrt.scm
(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-iter guess x) (if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(define (sqrt x) (sqrt-iter 1.0 x))
練習問題1.6
1-6.scm
(load "./sqrt.scm")
(print (sqrt 5)) ;; 元のsqrt
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
(print (new-if (= 2 3) 0 5)) ;;正しく動くことを確認
(print (new-if (= 1 1) 0 5))
(define (sqrt-iter guess x) (new-if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(print (sqrt 5)) ;; new-ifをつかったsqrt. 無限ループに陥る
(if ⟨predicate⟩ ⟨consequent⟩ ⟨alternative⟩)
if 式を評価するにあたって、インタプリタは最初に式の ⟨predicate⟩ の部分
を評価します。もし ⟨predicate⟩ の評価結果が真である場合、インタプリタは
⟨consequent⟩ を評価し、その値を返します。そうでなければ ⟨alternative⟩ を評
価し、その値を返します。
(19P参照)
condについて試してみる。
(define (p) (p))
(cond (#t 0)
(else (p)))
これは∞ループしない => elseは評価されていない。
if 同様 condも条件を頭から評価していく特殊形式
しかし、定義されたnew-ifは特殊形式ではない。
特殊形式でない式は引数が先にすべて評価してから、式を評価する。
そのため無限ループに陥った。
@hio さん
; new-if は特殊形式ではないので, 関数適用の実行前に全ての部分組み合わせの評価が
; 行われ, 結果 new-if の呼び出しの前に ``(good-enough? guess x)`` のみだけではなく
; ``guess`` そして ``(sqrt-iter (improve guess x) x)`` の評価も行われることになり
; sqrt-iter は無限の自己呼び出しに陥り, 制御を返さなくなってしまう.
new-ifはただの関数みたいなものなので
new-if(foo(), bar())
は、foo() と bar()を評価してから new-if を評価するよね
練習問題1.7
まだ
小さい値
しきい値0.001
の場合0.001
より小さい値の予測値は、0.001より大きな誤差となってしまう。
(print (sqrt 0.01))
;; 0.1が正しい。
;;だいたい近づく 0.10032578510960605
(print (sqrt 0.0001))
;; 0.01のはすだが
;;0.03230844833048122
のようになる。
まだ検証不足。数学的にちゃんと示そう(今後の課題)
大きい値
(みんなで検証中)
練習問題1.8
@hioさん
(define (square x) (* x x))
(define (cube x) (* x x x))
(define (cbrt-iter guess x)
(if (good-enough? guess x)
guess
(cbrt-iter (improve guess x) x)))
(define (improve guess x)
(/ (+ (/ x (square guess)) (* 2 guess)) 3))
(define (good-enough? guess x)
(< (abs (- (cube guess) x)) 0.001))
(define (cbrt x)
(cbrt-iter 1.0 x))
; gosh> (cbrt 1)
; 1.0
; gosh> (cbrt 8)
; 2.000004911675504
; gosh> (cbrt 27)
; 3.0000005410641766
; gosh> (cbrt 64)
; 4.000017449510739
; gosh> (cbrt 42)
; 3.476026657071078
; gosh> (* 3.476026657071078 3.476026657071078 3.476026657071078)
; 42.000000441671865
; gosh> (cbrt 57)
; 3.8485043229942804
; gosh> (cube (cbrt 57))
; 57.00014181732636
===
@miumixuさん
(define (improve guess x)
(/ (+ (/ x (square guess))
(* 2 guess))
3))
(define (good-enough? guess x)
(< (abs (- guess (improve guess x))) 0.001))
(define (cbrt-iter guess x)
(if (good-enough? guess x)
guess
(cbrt-iter (improve guess x) x)))
(define (cbrt x)
(cbrt-iter 1.0 x))
1.1.8ブラックボックス抽象化としての手続き
モジュールとして使えるようにプログラムを分解しよう〜ってお話でした。