SICP問題3.45

Louisが定義した払い出し、預け入れの直列化+直列変換器を輸出する口座の手続き

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

預け入れは元々のmake-accountのように扱う

(define (deposit account amount)
  ((account 'deposit) amount))

Louisの考えで何が悪いか?
特にserialized-exchangeを呼び出した場合、何が起きるか考えよ
という問題。
ということでserialized-exchangeの定義

(define (exchange account1 account2)
  (let ((differnece (- (account1 'balance)
                       (account2 'balance))))
    ((account1 'withdraw) difference)
    ((account2 'deposit) difference)))
(define (serialized-excahnge account1 account2)
  (let ((serializer1 (account1 'serializer))
        (serializer2 (account2 'serializer)))
    ((serializer1 (serializer2 exchange))
     account1
     account2)))

serialized-exchangeが呼ばれた場合、各アカウントは以下のように直列化されている

(serializer1 (serializer2 (serializer1 (withdraw account1 amount))))
(serializer1 (serializer2 (serializer2 (deposit account2 amount))))

withdrawの方は直列変換器が入れ子になっているためデッドロックになってしまい、処理が終わらない