Skip to content

Instantly share code, notes, and snippets.

@francoisdevlin
Created October 28, 2011 00:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save francoisdevlin/1321330 to your computer and use it in GitHub Desktop.
Save francoisdevlin/1321330 to your computer and use it in GitHub Desktop.
(defn gen-symbols [n] (map #(symbol (str "arg_" %)) (range 0 n)))
(def *invoke-max* 20)
(defn invoke-count [sym n]
(let [over-max? (> n *invoke-max*)
n (min n *invoke-max*)
in-args (gen-symbols n)]
(list 'invoke (vec (concat in-args (if over-max? '[& args] [])))
(apply list (concat (if over-max? '[apply]) [sym] in-args (if over-max? ['args]))))))
(defn gen-invoke [sym]
(concat
['clojure.lang.IFn (list 'applyTo '[args] (list 'apply sym '(seq args)))]
(map #(invoke-count sym %) (range 0 (+ 2 *invoke-max*)))))
(defmacro definvokable [sym & body]
"Has a 20 argument limit, supports vairadic arguments"
`(deftype ~@(concat body (gen-invoke sym))))
;;Usage
(definvokable f TestFn [f])
((TestFn +) 1) => 1
((TestFn +) 1 2) => 3
(apply (TestFn +) [1 2]) => 3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment