Edited at

オンラインSICP読書女子会 #2(1.1.7~1.1.8) まとめ

More than 3 years have passed since last update.

#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 は無限の自己呼び出しに陥り, 制御を返さなくなってしまう.

@cocodrips

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ブラックボックス抽象化としての手続き

モジュールとして使えるようにプログラムを分解しよう〜ってお話でした。