sicp-2-4
Posted on 2015-02-24 06:45:38 +0900 in SICP
2.73
(define global-array '())
(define (make-entry k v) (list k v))
(define (key entry) (car entry))
(define (value entry) (cadr entry))
(define (put op type item)
(define (put-helper k array)
(cond ((null? array) (list(make-entry k item)))
((equal? (key (car array)) k) array)
(else (cons (car array) (put-helper k (cdr array))))))
(set! global-array (put-helper (list op type) global-array)))
(define (get op type)
(define (get-helper k array)
(cond ((null? array) #f)
((equal? (key (car array)) k) (value (car array)))
(else (get-helper k (cdr array)))))
(get-helper (list op type) global-array))
(define (variable? x) (symbol? x))
(define (same-variable? v1 v2)
(and (variable? v1) (variable? v2) (eq? v1 v2)))
(define (sum? x)
(and (pair? x) (eq? (car x) '+)))
(define (deriv exp var)
(cond ((number? exp) 0)
((variable? exp) (if (same-variable? exp var) 1 0))
(else ((get 'deriv (operator exp)) (operands exp)
var))))
(define (operator exp) (car exp))
(define (operands exp) (cdr exp))
(define (attach-tag type-tag contents)
(if (= type-tag 'scheme-number)
contents
(cons type-tag contents)))
(define (type-tag datum)
(cond ((number? datum) 'scheme-number)
((pair? datum) (car datum))
(else (error "Bad tagged datum -- TYPE-TAG" datum))))
(define (contents datum)
(cond ((number? datum) datum)
((pair? datum) (cdr datum))
(else (error "Bad tagged datum -- CONTENTS" datum))))
(define (install-deriv-package)
(define (=number? exp num)
(and (number? exp) (= exp num)))
(define (make-sum a1 a2)
(cond ((=number? a1 0) a2)
((=number? a2 0) a1)
((and (number? a1) (number? a2)) (+ a1 a2))
(else (list '+ a1 a2))))
(define (addend data) (car data))
(define (augend data) (cadr data))
(define (deriv-sum data var)
(make-sum (deriv (addend data) var)
(deriv (augend data) var)))
(define (make-product m1 m2)
(cond ((or (=number? m1 0) (=number? m2 0)) 0)
((=number? m1 1) m2)
((=number? m2 1) m1)
((and (number? m1) (number? m2)) (* m1 m2))
(else (list '* m1 m2))))
(define (multiplier data) (car data))
(define (multiplicand data) (cadr data))
(define (deriv-product data var)
(make-sum
(make-product (multiplier data)
(deriv (multiplicand data) var))
(make-product (deriv (multiplier data) var)
(multiplicand data))))
(define (make-exponentiation base exp)
(cond ((=number? exp 0) 1)
((=number? exp 1) base)
(else (list '** base exp))))
(define (base data) (car data))
(define (exponent data) (cadr data))
(define (deriv-exponentation data var)
(make-product
(exponent data)
(make-product
(make-exponentiation (base data)
(make-sum (exponent data) (- 1)))
(deriv (base data) var))))
(put 'deriv '+ deriv-sum)
(put 'deriv '* deriv-product)
(put 'deriv '** deriv-exponentation)
'done)
(install-deriv-package)
(deriv '(** (+ (** x 2) 1) 2) 'x)put and get is from stackoverflow.
2.75
(define (make-from-mag-ang r a)
(define (dispatch op)
(cond ((eq? op 'real-part) (* r (cos a)))
((eq? op 'imag-part) (* r (sin a)))
((eq? op 'magnitude) r)
((eq? op 'angle) a)
(else
(error "Unknown op -- MAKE-FROM-MAG-ANG" op))))
dispatch)2.76
Message passing style is more flexible compared with data driven style, which is self contained.
But message passing suffers from the only generic procedures of one argument.
Hide Comments
comments powered by Disqus