I'd like to propose different implementation of defnk, attached below. Defnk2 translates keyword arguments to positional arguments at compile time, and is therefore about 36x faster on my machine.
(defn expand-keyword-call [name pos kw-defaults args] (if (< (count args) (count pos)) (throw (Exception. "Too few arguments to " name))) `(~(symbol (str name "*")) ~@(take (count pos) args) ~@(loop [;; current keyword args left to process kwargs (drop (count pos) args) ;; current keyword values kwvals (apply hash-map kw-defaults)] (cond (= (count kwargs) 0) (map #(kwvals %) (take-nth 2 kw-defaults)) (not (contains? kwvals (first kwargs))) (throw (Exception. (str "Unknown keyword argument to " name ": " (first kwargs)))) (= (count kwargs) 1) (throw (Exception. (str "No value for keyword argument " (first kwargs) " in call to " name))) true (recur (drop 2 kwargs) (assoc kwvals (first kwargs) (second kwargs))))))) (defmacro defnk2 [name args & body] (let [ [pos kwvals] (split-with symbol? args)] `(do (defn ~(symbol (str name "*")) ~(vec (concat pos (map #(symbol (.getName %)) (take-nth 2 kwvals)))) ~@body) (defmacro ~name [& args#] (expand-keyword-call '~name '~pos '~kwvals args#)) (.setMeta #'~name (assoc (meta #'~name) :arglists '(~args) ))))) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en