(defn diff [expr var] (cond (symbol? expr) (if (= expr var) 1 0) (number? expr) 0 (match expr [op & args] (case op '+ ['+ ;(map |(diff $ var) args)] '* (let [[a b] args] ['+ ['* (diff a var) b] ['* a (diff b var)]]) (errorf "unknown op: %v" op))))) (pp (diff '(+ (* x x) 3) 'x)) (pp (diff '(+ x 3) 'x))