問題3.5 〜3.15

問題3.5 モンテカルロ積分

ちょっとイメージがつかめないのでスキップ

問題3.6 乱数を作成する関数を返すような手続き?

ちょっとやり方がよく分からないのでスキップ

問題3.7 問題3.3 に別の名前とパスワードでもアクセスできるような手続きを定義する。

(define (make-account balance passwd)
  (define (withdraw amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount))
               balance)
        "Insufficient funds"))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (define (dispatch pass m)
    (if (eq? passwd pass)
        (cond ((eq? m 'withdraw) withdraw)
              ((eq? m 'deposit) deposit)
              (else (error "Unknown request -- MAKE-ACCOUNT"
                           m)))
        (error "Incorrect password" m)))
  dispatch)

(define (make-joint account old_pass new_pass)
  (set! account (make-account 
                   ((account old_pass 'withdraw) 0) new_pass))
  account)

3.3には変更を加えなかった。以前のアカウントを別のパスワードを持つようにして上書きした。以前のパスワードも保ったままだとすると少し3.3に変更を加える必要がありそう。0円を引き落とすと現在の全所持金を戻り値として返すのを利用した。

問題3.8 (+ (f 0) (f 1)) が左から評価されると0を返し、右から評価されると1を返すような手続きfを定義する。

(define (f n)
  (if (= n 0)
    (begin (set! f (lambda (x) 0))
           0)
    n))

(f 0)が実行されるとfを書き換えて引数に何を与えても0を返すようにした。

3.2 評価の環境モデル

変数を宣言するというのはそのスコープの中にある名前を束縛するということを意味するそうな。

問題3.9 階乗を計算する手続きの再帰版、反復版それぞれの環境を図にかけ

コードを書く問題じゃないのでスキップ

問題3.10, 11, 12

省略。なんかとばしてばっかりだな…(汗。

問題3.13 (last-pair z)を計算しようとすると何が起こるか

(set-cdr! (last-pair x) x)でxがもともと(1 . (2 . (3 . 4)))だとすると、(last-pair x)は(3 . 4)であるが、これをxと置き換えるので、(1 . (2 . (1 . (2 . ( ..... )))))というように無限ループが続くことになる。

問題3.14 (mystery x)

guile> (mystery '(1 2 3 4))
(4 3 2 1)

ということでリストを逆順にする手続き。

問題3.15

省略。

問題3.16〜19は考え中。

スキップばかりしてるようだけど分からなかったらどんどん飛ばしていっても良いと思う。あとになって戻ってみたら案外簡単に解けるようになっているのを期待して…*1

*1:もちろんそのためにはある程度アタマを使って考えることも必要であるけれど