(sicp30)m2.77~m2.78

この先の問題もけっこう楽にできそう。

;;m2.77
(use ggc.debug.trace)
(let ()
  (trace apply-generic)
;;  (untrace)
  (define z (make-from-real-imag 3 4))
  (magnitude z))

;; 4:user> 0:(apply-generic magnitude (complex rectangular  ...
;; 1:  (apply-generic magnitude (rectangular 3 . 4))
;;     ->5.0
;;   ->5.0
;; ; trace: apply-generic has been called 2 times.
;; => 5.0

;;というわけで2回


;;m2.78
;;type-tag contents attach-tagを変更すればいい。
;;しばらく、この辺でここのあたりで悩んでいたので余裕。


;;元の関数。(これを変更していく)
(define (attach-tag type-tag contents)
  (cons type-tag contents))

(define (type-tag datum)
  (if (pair? datum)
      (car datum)
      (error "Bad tagged datum -- TYPE-TAG" datum)))

(define (contents datum)
  (if (pair? datum)
      (cdr datum)
      (error "Bad tagged datum -- CONTENTS" datum)))

;;---
(define (attach-tag type-tag contents)
  (if (eq? type-tag 'scheme-number)
      contents
      (cons type-tag contents)))


(define (type-tag datum)
  (cond ((pair? datum) (car datum))
        ((number? datum) 'scheme-number)
        (else
         (error "Bad tyagged datum -- TYPE-TAG" datum))))

(define (contents datum)
  (cond ((pair? datum) (cdr datum))
        ((number? datum) datum)
        (else
         (error "Bad tagged datum -- CONTENTS" datum))))


;;これで終了。
;;確かめ。
(let* ((sn1 (make-scheme-number 10))
      (sn2 (make-scheme-number 20))
      (exp1 (lambda (op) (op sn1 sn2)))
      (exp2 (lambda (op) (op 10 20))))
  (list (= (exp1 add) (exp2 add))
        (= (exp1 sub) (exp2 sub))
        (= (exp1 mul) (exp2 mul))
        (= (exp1 div) (exp2 div))))
           
;;14:user> => (#t #t #t #t)