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


[#ladiescpp](http://ladiespp.connpass.com/) の主催してる [オンラインSICP読書女子会 2 - connpass](http://ladiespp.connpass.com/event/26232/)のまとめです〜。
まちがっているところがあればどんどんコメントください(｀･ω･´)ゞ

次回の参加は [オンラインSICP読書女子会 #3 (1.2.1~1.2.2) - connpass](http://ladiespp.connpass.com/event/26650/) から！

**参加者のブログ**
[オンラインSICP読書女子会 #2 (1.1.7~1.1.8) — miumixu's tech blog](http://miumixu.github.io/blog/2016/02/04/sicp-reading-girls-meetup-at-online2.html)
## 1.1.7

ニュートン法による平方根のお話。


sqrt.scm

```lisp
(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

```lisp
(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](http://qiita.com/hio-harp) さん

```
; 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](http://qiita.com/hio-harp)さん 

```lisp
(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](http://qiita.com/miumixu)さん

```lisp
(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ブラックボックス抽象化としての手続き
モジュールとして使えるようにプログラムを分解しよう〜ってお話でした。