Skip to content

Instantly share code, notes, and snippets.

@achim
Created July 4, 2009 11:04
Show Gist options
  • Save achim/140529 to your computer and use it in GitHub Desktop.
Save achim/140529 to your computer and use it in GitHub Desktop.
(defn arities
"*HACK*
Returns a seq of arities of f. The seq will be infinite if f uses rest-params,
starting at the minimum number of args."
[f]
(let [invokes (filter #(= "invoke" (.getName %)) (.getDeclaredMethods (class f)))
arities (sort (map #(count (.getParameterTypes %)) invokes))]
(if (instance? clojure.lang.RestFn f)
(concat arities (iterate inc (inc (last arities))))
arities)))
(comment
user> (take 10 (arities (fn ([a b c])([a b c & d] ))))
(3 4 5 6 7 8 9 10 11 12)
user> (take 10 (arities (fn ([a b c])([a b c d] ))))
(3 4)
)
(defn stack [& exprs]
(letfn [(do-stack [stk [e & es :as exprs]]
(if e
(let [consume (if (fn? e) (first (arities e)) 0)
[in remaining] (split-at consume stk)
push (if (fn? e) (apply e in) e)]
(recur (conj remaining push) es))
stk))]
(do-stack () exprs)))
(defn add [x y] (+ x y))
(comment
user> (stack 1 2 add 5 6 add 7 add add)
(21)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment