 (ns clojure-club.macros.mbastian
-  (:require [taoensso.tufte :as tufte :refer (defnp p profiled profile)]))
+  (:require [taoensso.tufte :as tufte :refer (defnp p profiled profile)]
+            [clojure.pprint :as pp]))
 
 ;Techniques for manual polynomial creation
 (defn canonical-fn [t]


;Macros that allow for definition of complex polynomials with the convenience
;of a coefficients vector and the performance of manual expansion.
(defmacro defpoly-canonical [n terms]
  (let [t# (eval terms)]
    `(defn ~n [~'t]
       (+ ~@(for [i (range (count t#)) :let [c (t# i)]]
              `(* ~c ~@(repeat i 't)))))))

(defmacro defpoly-horner [n terms]
  (let [t# (rseq (eval terms))]
    `(defn ~n [~'t]
     ~(reduce (fn [b a] `(+ ~a (* ~b ~'t))) t#))))

;Macroexpand to see what happend
(macroexpand
  '(defpoly-canonical canonical-poly-macro [134.96340251 477198.8675605 0.0088553 1.4343E-5]))

(macroexpand
  '(defpoly-horner horner-poly-macro [134.96340251 477198.8675605 0.0088553 1.4343E-5]))

;Define the functions
(defpoly-canonical canonical-poly-macro [134.96340251 477198.8675605 0.0088553 1.4343E-5])
(defpoly-horner horner-poly-macro [134.96340251 477198.8675605 0.0088553 1.4343E-5])

(canonical-poly-macro 0.0426236319)
(horner-poly-macro 0.0426236319)

(def coefficients
  (vec (repeatedly 100 (comp dec #(* 2 %) rand))))

(macroexpand '(canonical-expand coefficients))

(def big-canonical
  (canonical-expand coefficients))

(def big-horner
  (horner-expand coefficients))

(profile
  {:dynamic? true}
