Clojure: Generating functions from template -


i have following code generic conversion library:

(defn using-format [format] {:format format})  (defn- parse-date [str format]   (.parse (java.text.simpledateformat. format) str))  (defn string-to-date   ([str]      (string-to-date str (using-format "yyyy-mm-dd")))   ([str conversion-params]      (parse-date str (:format (merge (using-format "yyyy-mm-dd") conversion-params))))) 

i need able call this:

(string-to-date "2011-02-17")  (string-to-date "2/17/2011" (using-format "m/d/yyyy"))  (string-to-date "2/17/2011" {}) 

the third case problematic: map not contain key :format critical function. that's why merge default value.

i need have dozen of similar functions conversions between other types. there more elegant way not require me copy-paste, use merge etc. in every single function?

ideally, looking (macro?):

(defn string-to-date   (wrap      (fn [str conversion-params]         (parse-date str (:format conversion-params))) ; implementation      {:format "yyyy-mm-dd"})) ; default conversion-params 

... produce overloaded function (unary , binary), binary having merge in first example.

so define little more strictly, want create macro creates converter functions. converter function function 2 arities, 1 argument , 2 arguments. first argument converter function object converted. second argument map of options, somehow affect conversion (like format string in example.)

a default parameter map can specified. when called 1 argument, converter function use default parameter map. when called 2 arguments, converter function merge default parameter map passed in parameter map, such passed in parameters override defaults if exist.

let's call macro def-converter. def converter take 3 arguments, first name of function created. second anonymous function of 2 arguments implements two-arity converter, without default parm merging. third argument default parm map.

something work:

(defmacro def-converter [converter-name converter-fn default-params]   (defn ~converter-name    ([to-convert#]      (let [default-params# ~(eval default-params)]        (~converter-fn to-convert# default-params#)))    ([to-convert# params#]      (let [default-params# ~(eval default-params)]       (~converter-fn to-convert# (merge default-params# params#)))))) 

then can use like:

(def-converter    string-to-date     (fn [to-convert conversion-params]      (parse-date to-convert conversion-params))   (using-format "yyyy-mm-dd")) 

but have make change 1 of helper functions:

(defn- parse-date [str params]    (.parse (java.text.simpledateformat. (:format params)) str)) 

this because macro needs general enough handle arbitrary maps of parameters, can't count on. there ways around it, can't think of 1 offhand that's not messier pushing off onto helper function (or anonymous function needs passed def-converter).


Comments

Popular posts from this blog

apache - Add omitted ? to URLs -

redirect - bbPress Forum - rewrite to wwww.mysite prohibits login -

php - How can I stop spam on my custom forum/blog? -