From 1fcebbc1d9fad13970b6675fac0c941cd8e3a57d Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <vu3rdd@gmail.com>
Date: Sat, 2 Oct 2010 00:01:11 +0530
Subject: [PATCH] solution to 2.77, 2.88, 2.79, 2.80

---
 src/sicp/ex2_77.rkt | 54 +++++++++++++++++++++++++++++++++++++++++++++
 src/sicp/ex2_78.rkt | 23 +++++++++++++++++++
 src/sicp/ex2_79.rkt | 30 +++++++++++++++++++++++++
 src/sicp/ex2_80.rkt | 24 ++++++++++++++++++++
 4 files changed, 131 insertions(+)
 create mode 100644 src/sicp/ex2_77.rkt
 create mode 100644 src/sicp/ex2_78.rkt
 create mode 100644 src/sicp/ex2_79.rkt
 create mode 100644 src/sicp/ex2_80.rkt

diff --git a/src/sicp/ex2_77.rkt b/src/sicp/ex2_77.rkt
new file mode 100644
index 0000000..8d6d348
--- /dev/null
+++ b/src/sicp/ex2_77.rkt
@@ -0,0 +1,54 @@
+#lang racket
+#|
+magnitude is defined in section 2.4.3 as:
+
+(define (magnitude z) (apply-generic 'magnitude z))
+
+In this example z looks as '(complex rectangular 3 . 4))
+
+The apply-generic procedure is defined as follows:
+
+(define (apply-generic op . args)
+  (let ((type-tags (map type-tag args)))
+    (let ((proc (get op type-tags)))
+      (if proc
+          (apply proc (map contents args))
+          (error
+            "No method for these types -- APPLY-GENERIC"
+            (list op type-tags))))))
+
+Here, we find the type-tag of z, in this case, it will be 'complex.
+The table constructed with the generic prodecure "magnitude" was using
+the type of z, namely 'rectangular. 
+
+The remedy as suggested by Alyssa is as follows:
+
+(put 'real-part '(complex) real-part)
+(put 'imag-part '(complex) imag-part)
+(put 'magnitude '(complex) magnitude)
+(put 'angle '(complex) angle)
+
+Now, this will add a new column for each of the operations (real-part, imag-part,
+magnitude and angle) for the type '(complex) and install the corresponding function.
+
+Now, when we do (type-tag z), we get 'complex and then we look for the type-specific
+procedure using (get op type-tag) which will give the right procedure.
+
+(apply-generic 'magnitude z)
+
+=> (apply-generic 'magnitude '(complex rectangular x . y)
+
+=> ((get 'magnitude 'complex) '(rectangular x . y) 
+
+=> (magnitude '(rectangular x . y))
+
+=> (apply-generic 'magnitude '(rectangular x . y))
+
+=> ((get 'magnitude 'rectangular) '(x . y))
+
+So, apply-generic gets invoked twice.
+
+
+(
+
+|#
diff --git a/src/sicp/ex2_78.rkt b/src/sicp/ex2_78.rkt
new file mode 100644
index 0000000..e751b52
--- /dev/null
+++ b/src/sicp/ex2_78.rkt
@@ -0,0 +1,23 @@
+#lang racket
+
+;; modify type-tag, contents, and attach-tag so that primitive numbers need not
+;; be tagged.
+
+(define (type-tag datum)
+  (cond 
+    [(pair? datum) (car datum)]
+    [(number? datum) 'scheme-number]
+    [else 
+     (error "Bad tagged datum -- TYPE-TAG" datum)]))
+
+(define (contents datum)
+  (cond 
+    [(pair? datum) (cdr datum)]
+    [(number? datum) datum]
+    [else
+     (error "Bad tagged datum -- CONTENTS" datum)]))
+
+(define (attach-tag type-tag contents)
+  (if (number? contents)
+      contents
+      (cons type-tag contents)))
diff --git a/src/sicp/ex2_79.rkt b/src/sicp/ex2_79.rkt
new file mode 100644
index 0000000..560d380
--- /dev/null
+++ b/src/sicp/ex2_79.rkt
@@ -0,0 +1,30 @@
+#lang racket
+
+(define (equ? x y) (apply-generic 'equ? x y))
+
+(define (install-scheme-number-package)
+  (define (equ? x y)
+    (= x y))
+  (put 'equ? '(scheme-number scheme-number) equ?)
+  'done)
+
+(define (install-rational-number-package)
+  (define (equ? r1 r2)
+    (let* ([n1 (numer r1)]
+           [d1 (denom r1)]
+           [n2 (numer r2)]
+           [d2 (denom r2)]
+           [g1 (gcd n1 d1)]
+           [g2 (gcd n2 d2)])
+      (and (= (/ n1 g1) (/ n2 g2))
+           (= (/ d1 g1) (/ d2 g2)))))
+  (put 'equ? '(rational rational) equ?)
+  'done)
+
+(define (install-complex-number-package)
+  (define (equ? z1 z2)
+    (and (= (real-part z1) (real-part z2))
+         (= (imag-part z1) (imag-part z2))))
+  (put 'equ? '(complex complex) equ?)
+  'done)
+  
\ No newline at end of file
diff --git a/src/sicp/ex2_80.rkt b/src/sicp/ex2_80.rkt
new file mode 100644
index 0000000..59fe926
--- /dev/null
+++ b/src/sicp/ex2_80.rkt
@@ -0,0 +1,24 @@
+#lang racket
+
+(define (=zero? x) (apply-generic '=zero? x))
+
+(define (install-scheme-number-package)
+  (define (=zero? x)
+    (zero? x))
+  (put '=zero? '(scheme-number) =zero?)
+  'done)
+
+(define (install-rational-number-package)
+  (define (=zero? r)
+    (zero? (numer r)))
+  (put '=zero? '(rational) =zero?)
+  'done)
+
+(define (install-complex-number-package)
+  (define (=zero? z)
+    (and (zero? (real-part z))
+         (zero? (imag-part z))))
+  (put '=zero? '(complex) =zero?)
+  'done)
+        
+  
\ No newline at end of file
-- 
2.45.2