 (ns util.funxions
   (:require [runtime.q :as q])
   (:require [backtick])
+  (:require clojure.pprint)
   )
 
 ;check this:

  ;TODO: allow invariants functions for each param and throw when any of them fail(obviously)
  ;TODO: ignore optional params that weren't passed on call
  ;TODO: throw when required params aren't passed on call
  (println firsta)
  )
)



(defmacro defxn ;def funxion
  [fname ;funxion name
   passedDefBlock; a map
   & codeblocks ;multiple forms as code
   ]
  (let [x (eval (list
            'backtick/template;-fn
            ;backtick/syntax-quote-fn 
            passedDefBlock))
        ;e (eval x)
        ]
    (println x)
    ;(println e)
    `(defn ~fname [& all#]
       (let [~'fxn_defblock '~x 
             ~'fxn_rawDefBlock '~passedDefBlock
             ;~'fxn_evalled ~e
             ]
         (println "raw" ~'fxn_rawDefBlock)
         (println "defblock" ~'fxn_defblock)
         ;(println ~e)
         ~@codeblocks
         )
       )
    )
  )
#_(
=> (defxn noes {:a ~(inc (+ 1 2)) :b firsta}
     (println "!!!" fxn_defblock)
     (:b fxn_defblock)
     )
{:a 4, :b firsta}
#'util.funxions/noes
=> (noes)
raw {:a (clojure.core/unquote (inc (+ 1 2))), :b firsta}
defblock {:a 4, :b firsta}
!!! {:a 4, :b firsta}
firsta
)

#_(
=> (defxn noes {:a ~(inc 1) :b firsta}
     (println defblock)
     )
(clojure.core/apply clojure.core/hash-map (clojure.core/concat [(quote :a) (inc 1) (quote :b) (quote firsta)]))
{:a 2, :b firsta}
#'util.funxions/noes
=> (noes)
raw {:a (clojure.core/unquote (inc 1)), :b firsta}
defblock {:a 2, :b firsta}
{:a 2, :b firsta}
nil
)

(clojure.pprint/pprint 

