3.1〜3.4まで
id:higeponさんやg:sicp:id:hyukiさんなどとペースをあわせた方が問題意識が共有できて良いかと思われるのでちょっとすっ飛ばして3章から再開する。予想通り基礎の抜け落ちているオイラには厳しい…。
問題3.1
accumulatorを返す手続きを定義。accumulatorはrubyでいうところのinjectで良いのかな?
; make-accummlater (define (make-accumulator amount) (lambda (step) (set! amount (+ amount step)) amount))
問題3.2
(define (make-monitored proc) (define counter 0) (define (run-proc arg) (set! counter (+ counter 1)) (proc arg)) (define (dispatch m) (cond ((eq? m 'how-many-calls?) counter) (else (run-proc m)))) dispatch)
最初counterをrun-proc内で局所変数としていてハマった。
問題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)
例題をパスワードをチェックさせるようにとのこと。SICPは例題をベースにして問題が出てくるところがすごくよいと思う。中高の数学の教科書みたいな感じ。例も問題もより具体的だけど。
問題3.4
(define (make-account balance passwd) (define counter 0) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (define call-the-cops "call cops!!") (define (dispatch pass m) (if (eq? passwd pass) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m))) (begin (set! counter (+ counter 1)) (if (< counter 7) ("Incorrect password") (call-the-cops))))) dispatch)
7回も入力するのがめんどくさかったため未実行。おそらく大丈夫だと思う。こういうときこそテストを自動生成するプログラムを書けば勉強になるんだろうなぁ…と思いつつやらない人。
それにしても勉強しながら勉強日記を書いてるわけではないからなかなか更新がつらいし日記をつける効果もそれほどないかもしれない。はてなダイアリーライターでも導入してみようかな…。