   (cond
     (number? expr) 0
     (symbol? expr) (if (= expr var) 1 0)
-    (sum? expr) (list* '+ (map  #(derivative % var) (rest expr)))
-    (prod? expr) (list* '+ (derivative-prod (rest expr) var))
+    (sum? expr) (make-sum (map  #(derivative % var) (rest expr)))
+    (prod? expr) (make-sum (derivative-prod (rest expr) var))
     ))
 
 ;; ---------------------------------------------------------------

  (prn (derivative 'x 'x))
  (prn (derivative 'x 'y))
  (prn (derivative `x `x))
  
  (prn (derivative (list '+ 'x 1) 'x))
  (prn (derivative `(+ x 1) `x))
  (prn (derivative `(* x 2) `x))
  
  (prn (derivative `(+ x (* x x y)) `x))
  )


  [expr]
  (or
    (= (first expr) '*) ;; Works with simple quote
    (= (first expr) `*) ;; Works with syntax quote
    ))

(defn sum?
  [expr]
  (or
    (= (first expr) '+) ;; Works with simple quote
    (= (first expr) `+) ;; Works with syntax quote
    ))

(defn make-sum
  "Simplify the sum, adding the constants together"
  [terms]
  (let [parts (group-by number? terms)
        number-sum (reduce + (parts true))]
    (cond
      (empty? (parts true)) (list* '+ (parts false))
      (empty? (parts false)) number-sum
      :else (list* '+ number-sum (parts false))
      )))

(defn make-product
  "Simplify the product, multiplying the constants together"
  [terms]
  (let [parts (group-by number? terms)
        product (reduce * (parts true))]
    (cond
      (empty? (parts true)) (list* '* (parts false))
      (empty? (parts false)) product
      (zero? product) 0
      :else (list* '* product (parts false))
      )))

(declare derivative)

(defn derivative-prod
  [terms var]
  (for [r (rotations terms)]
    (make-product (conj (rest r) (derivative (first r) var)))
    ))

(defn derivative
