Blame


1 665c255d 2023-08-04 jrmu (define (exchange account1 account2)
2 665c255d 2023-08-04 jrmu (let ((difference (- (account1 'balance)
3 665c255d 2023-08-04 jrmu (account2 'balance))))
4 665c255d 2023-08-04 jrmu ((account1 'withdraw) difference)
5 665c255d 2023-08-04 jrmu ((account2 'deposit) difference)))
6 665c255d 2023-08-04 jrmu
7 665c255d 2023-08-04 jrmu (define (make-account-and-serializer balance)
8 665c255d 2023-08-04 jrmu (define (withdraw amount)
9 665c255d 2023-08-04 jrmu (if (>= balance amount)
10 665c255d 2023-08-04 jrmu (begin (set! balance (- balance amount))
11 665c255d 2023-08-04 jrmu balance)
12 665c255d 2023-08-04 jrmu "Insufficient funds"))
13 665c255d 2023-08-04 jrmu (define (deposit amount)
14 665c255d 2023-08-04 jrmu (set! balance (+ balance amount))
15 665c255d 2023-08-04 jrmu balance)
16 665c255d 2023-08-04 jrmu (let ((balance-serializer (make-serializer)))
17 665c255d 2023-08-04 jrmu (define (dispatch m)
18 665c255d 2023-08-04 jrmu (cond ((eq? m 'withdraw) withdraw)
19 665c255d 2023-08-04 jrmu ((eq? m 'deposit) deposit)
20 665c255d 2023-08-04 jrmu ((eq? m 'balance) balance)
21 665c255d 2023-08-04 jrmu ((eq? m 'serializer) balance-serializer)
22 665c255d 2023-08-04 jrmu (else (error "Unknown request -- MAKE-ACCOUT"
23 665c255d 2023-08-04 jrmu m))))
24 665c255d 2023-08-04 jrmu dispatch))
25 665c255d 2023-08-04 jrmu
26 665c255d 2023-08-04 jrmu (define (deposit account amount)
27 665c255d 2023-08-04 jrmu (let ((s (account 'serializer))
28 665c255d 2023-08-04 jrmu (d (account 'deposit)))
29 665c255d 2023-08-04 jrmu ((s d) amount)))
30 665c255d 2023-08-04 jrmu
31 665c255d 2023-08-04 jrmu (define (serialized-exchange account1 account2)
32 665c255d 2023-08-04 jrmu (let ((serializer1 (account1 'serializer))
33 665c255d 2023-08-04 jrmu (serializer2 (account2 'serializer)))
34 665c255d 2023-08-04 jrmu ((serializer1 (serializer2 exchange))
35 665c255d 2023-08-04 jrmu account1
36 665c255d 2023-08-04 jrmu account2)))
37 665c255d 2023-08-04 jrmu
38 665c255d 2023-08-04 jrmu ;; Exercise 3.44. Consider the problem of transferring an amount from one account to another. Ben Bitdiddle claims that this can be accomplished with the following procedure, even if there are multiple people concurrently transferring money among multiple accounts, using any account mechanism that serializes deposit and withdrawal transactions, for example, the version of make-account in the text above.
39 665c255d 2023-08-04 jrmu
40 665c255d 2023-08-04 jrmu (define (transfer from-account to-account amount)
41 665c255d 2023-08-04 jrmu ((from-account 'withdraw) amount)
42 665c255d 2023-08-04 jrmu ((to-account 'deposit) amount))
43 665c255d 2023-08-04 jrmu
44 665c255d 2023-08-04 jrmu ;; Louis Reasoner claims that there is a problem here, and that we need to use a more sophisticated method, such as the one required for dealing with the exchange problem. Is Louis right? If not, what is the essential difference between the transfer problem and the exchange problem? (You should assume that the balance in from-account is at least amount.)
45 665c255d 2023-08-04 jrmu
46 665c255d 2023-08-04 jrmu ;; Louis is wrong. The difference here is that the value in amount is still valid even if other processes change the balances within the two accounts. With difference, if any of the balances change, the amount that needs to be transferred is no longer valid. That is why if two processes alter any of the same accounts, the events cannot be interleaved. However, here, the amount that needs to be transferred will still be valid even if other processes change any of the accounts concurrently.