理系学生日記

おまえはいつまで学生気分なのか

問題3-42 (3.4.1 The Nature of Time in Concurrent Systems)

これが make-account なわけだけど,'withdraw とか 'deposit とかのメッセージが送られてくる毎に,毎回直列化された関数を生成するようになってる.

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

Ben がそれ時間のムダじゃね?みたいなことを言い出して,こんな風に書き直した.

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

有り体に言えば,あらかじめ直列化した関数を作っとけやアホか,って話で,SICP のこれまでの流れだと,これどこか間違っている感じなんだけど,どうも正しいっぽいんだよなー.たぶん正しい.安全.Ben たまにはやるな.