LoginSignup
3
3

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-02-03

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

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

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3