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