corrected solution to 3.45
authorRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Fri, 17 Jun 2011 15:05:43 +0000 (20:35 +0530)
committerRamakrishnan Muthukrishnan <vu3rdd@gmail.com>
Fri, 17 Jun 2011 15:05:43 +0000 (20:35 +0530)
src/sicp/ex3_45.rkt

index f3dd618712c1cf197d3cd60a605c15eefa9c6c82..8176e709ad16376248040355c87bc2a19fcb29f2 100644 (file)
@@ -2,13 +2,45 @@
 
 #|
 
-Deposits and Withdrawals are fine. But when it comes to exchange, we need a
-"mutually serialized" procedure with something like this:
+(define (exchange account1 account2)
+  (let ((difference (- (account1 'balance)
+                       (account2 'balance))))
+    ((account1 'withdraw) difference)
+    ((account2 'deposit) difference)))
 
- (serializer-1 (serializer-2 exchange))
+(define (serialized-exchange account1 account2)
+  (let ((serializer1 (account1 'serializer))
+        (serializer2 (account2 'serializer)))
+    ((serializer1 (serializer2 exchange))
+     account1
+     account2)))
 
-Otherwise, we are creating a "time hole" when another execution process can
-get hold of one of the account and deposit/withdraw from it which will make
-the end result of exchange erroneous.
+(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))
+
+Now let us see what happens when we call (serialized-exchange a1 a2)
+We invoke the procedure exchange serialized by the two serializers
+
+ ((s1 (s2 exchange)) a1 a2)
+
+Now, exchange will in turn, call serialized withdraw and deposit but
+it cannot do that because we are already calling a serialized procedure
+and so it will lock up waiting for the serializer.
 
 |#
\ No newline at end of file