From 1b0af65b90a33df862b0722af8d356940222f720 Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <vu3rdd@gmail.com>
Date: Fri, 17 Jun 2011 20:35:43 +0530
Subject: [PATCH] corrected solution to 3.45

---
 src/sicp/ex3_45.rkt | 44 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 38 insertions(+), 6 deletions(-)

diff --git a/src/sicp/ex3_45.rkt b/src/sicp/ex3_45.rkt
index f3dd618..8176e70 100644
--- a/src/sicp/ex3_45.rkt
+++ b/src/sicp/ex3_45.rkt
@@ -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
-- 
2.45.2