問題3-7〜8

「3.1.3 代入を取り入れた代価」では、関数型プログラミングと命令型プログラミングの違いや、「同一」「変化」など重要なキーワードについて語られていて、非常に示唆に富んだ節だと感じました。本書の後続の部分で何かにつまずいたら、ここに戻ってこようとも思っています。
問題3-7では、make-accountを複数人共同で使えるように機能強化します。残高情報は共有するが、user-idとpasswordは別に管理するという仕組みです。make-account本体の方を修正しなければという先入観があったため、上手いことこの要件を満たせるロジックを書けませんでした。そこで、ここの解答例を見てしまいました。残念です。make-jointの方で追加ユーザーのパスワードを局所化するようラッピングすればいいということに気づけませんでした。

(define (make-joint original-acc original-pw new-pw)
  (define (dispatch pw m)
    (if (eq? pw new-pw)
        (original-acc original-pw m)
        (lambda (x) "Incorrect pw")))
  dispatch)

(define takuya-acc (make-account 100 'takuya))

((takuya-acc 'takuya 'withdraw) 50)  ;=>50
    
(define paul-acc
  (make-joint takuya-acc 'takuya 'paul))
    
((paul-acc 'takuya 'deposit) 30)  ;=>"Incorrect pw"
((paul-acc 'paul 'deposit) 30)  ;=>80
((takuya-acc 'takuya 'withdraw) 40)  ;=>40
((takuya-acc 'paul 'withdraw) 40)  ;=>"Incorrect password"

問題3-8は、以下のような手続きを定義すると、(+ (f 0) (f 1))の評価順序によって返ってくる値が変わってしまいます。

(define f
  (let ((product 1))
    (lambda (x)
      (begin (set! product (* x product))
             product))))
(f 1)  ;=>1
(f 0)  ;=>0
(f 0)  ;=>0
(f 1)  ;=>0