Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What is going on with this article?
@cocodrips

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

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

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

3
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
3
Help us understand the problem. What is going on with this article?