From: Ramakrishnan Muthukrishnan Date: Fri, 1 Oct 2010 18:31:11 +0000 (+0530) Subject: solution to 2.77, 2.88, 2.79, 2.80 X-Git-Url: https://git.rkrishnan.org/?a=commitdiff_plain;h=1fcebbc1d9fad13970b6675fac0c941cd8e3a57d;p=sicp.git solution to 2.77, 2.88, 2.79, 2.80 --- 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