set!でデータの中身を変更できるようにすると参照透明性が失なわれてデータの同一性が判断できなくなるよ、というお話(かな?)
3.1
(define (make-accumulator acc) (lambda (n) (begin (set! acc (+ acc n)) acc)))
3.2
(define (make-monitored proc) (let ((calls 0)) (lambda (m) (cond ((eq? m 'how-many-calls?) calls) (else (begin (set! calls (+ calls 1)) (proc m)))) ) ))
3.3 (パスワード付き口座)
(define (make-account balance password) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (dispatch p m) (cond ((not (eq? p password)) (error "Incorrect password")) ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch)
3.4
(define (make-account balance password) (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) (display "('ω`)<お客さん、こっち来てもらえますか") (newline)) (let ((times-wrong 0)) (define (dispatch p m) (if (eq? p password) (begin (set! times-wrong 0) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) (begin (set! times-wrong (+ times-wrong 1)) (if (>= times-wrong 7) (call-the-cops) (error "Incorrect password"))))) dispatch))
ここから3.1.2.
rand-updateは http://www.cs.tau.ac.il/~scheme/mavo-fall-2001/Software/SICP/ch3support.scm で定義されているのを。
3.5
(define (random-in-range low high) (let ((range (- high low))) (+ low (random range)))) (define (estimate-integral P x1 x2 y1 y2 trials) (define (region-test) (P (random-in-range x2 x1) (random-in-range y2 y1))) (* (- x1 x2) (- y1 y2) (monte-carlo trials region-test)))
3.6
(define random-init 100) (define rand (let ((x random-init)) (lambda (m) (cond ((eq? m 'generate) (begin (set! x (rand-update x)) x)) ((eq? m 'reset) (lambda (new-value) (set! x new-value) x)) (else (error "Unknown method" m)) ))))
(rand 'generate) ; => 59 (rand 'generate) ; => 95 (rand 'generate) ; => 51 (rand 'generate) ; => 6 ((rand 'reset) 100) (rand 'generate) ; => 59 (rand 'generate) ; => 95 (rand 'generate) ; => 51 (rand 'generate) ; => 6
3.7
(define (make-joint account password new-password) (define (dispatch p m) (if (not (eq? p new-password)) (error "Incorrect password") (account password m))) dispatch)
3.8
引数の評価順序によって結果の異なる関数適用ができてしまう。
(define f (let ((x #f)) (lambda (n) (if x x (begin (set! x n) x)))))