]> git.rkrishnan.org Git - sicp.git/blob - src/sicp/ex2_56.clj
Solution to 4.44. A bit too verbose. Can be improved by better
[sicp.git] / src / sicp / ex2_56.clj
1 (ns sicp.ex2_56
2   (:use [sicp.ch2_3 :exclude (deriv)]
3         [sicp.utils]
4         [clojure.test]))
5
6 (declare exponentiation? exponent base make-exponentiation)
7
8 (defn deriv [exp var]
9   (cond (number? exp) 0
10         (variable? exp) (if (same-variable? exp var) 1 0)
11         (sum? exp) (make-sum (deriv (addend exp) var)
12                              (deriv (augend exp) var))
13         (product? exp) (make-sum (make-product (multiplier exp)
14                                                (deriv (multiplicand exp) var))
15                                  (make-product (deriv (multiplier exp) var)
16                                                (multiplicand exp)))
17         (exponentiation? exp) (make-product (exponent exp)
18                                             (make-product (make-exponentiation (base exp)
19                                                                                (- (exponent exp) 1))
20                                                           (deriv (base exp) var)))
21         :else (error "unknown expression type -- derive")))
22
23 (defn exponentiation? [exp]
24   (= (first exp) '**))
25
26 (defn base [exp]
27   (second exp))
28
29 (defn exponent [exp]
30   (second (rest exp)))
31
32 (defn make-exponentiation [b n]
33   (cond (=number? b 1) 1
34         (=number? b 0) 0        
35         (=number? n 1) b
36         (=number? n 0) 1
37         (and (number? b) (number? n)) (Math/pow b n)
38         :else (list '** b n)))