]> git.rkrishnan.org Git - sicp.git/blob - src/sicp/ex3_45.rkt
Merge branch 'master' of github.com:vu3rdd/sicp
[sicp.git] / src / sicp / ex3_45.rkt
1 #lang racket
2
3 #|
4
5 (define (exchange account1 account2)
6   (let ((difference (- (account1 'balance)
7                        (account2 'balance))))
8     ((account1 'withdraw) difference)
9     ((account2 'deposit) difference)))
10
11 (define (serialized-exchange account1 account2)
12   (let ((serializer1 (account1 'serializer))
13         (serializer2 (account2 'serializer)))
14     ((serializer1 (serializer2 exchange))
15      account1
16      account2)))
17
18 (define (make-account-and-serializer balance)
19   (define (withdraw amount)
20     (if (>= balance amount)
21         (begin (set! balance (- balance amount))
22                balance)
23         "Insufficient funds"))
24   (define (deposit amount)
25     (set! balance (+ balance amount))
26     balance)
27   (let ((balance-serializer (make-serializer)))
28     (define (dispatch m)
29       (cond ((eq? m 'withdraw) (balance-serializer withdraw))
30             ((eq? m 'deposit) (balance-serializer deposit))
31             ((eq? m 'balance) balance)
32             ((eq? m 'serializer) balance-serializer)
33             (else (error "Unknown request -- MAKE-ACCOUNT"
34                          m))))
35     dispatch))
36
37 Now let us see what happens when we call (serialized-exchange a1 a2)
38 We invoke the procedure exchange serialized by the two serializers
39
40  ((s1 (s2 exchange)) a1 a2)
41
42 Now, exchange will in turn, call serialized withdraw and deposit but
43 it cannot do that because we are already calling a serialized procedure
44 and so it will lock up waiting for the serializer.
45
46 |#