views:

320

answers:

4

Given a function object or name, how can I determine its arity? Something like (arity func-name) .

I hope there is a way, since arity is pretty central in Clojure

A: 
user=> (defn test-func
         ([p1] "Arity was 1.")
         ([p1 p2] "Arity was 2.")
         ([p1 p2 & more-args] (str "Arity was " (+ 2 (count more-args)))))
#'user/test-func
user=> (test-func 1)
"Arity was 1."
user=> (test-func 1 2)
"Arity was 2."
user=> (test-func 1 2 3)
"Arity was 3"
user=> (test-func 1 2 3 4)
"Arity was 4"
user=> (test-func 1 2 3 4 5) ;...
"Arity was 5"
Anon
I don't want to *execute* the function in order to know its arity. And I don't want to change the function code for this
bugspy.net
+15  A: 

The arity of a function is stored in the metadata of the var.

(:arglists (meta #'str))
;([] [x] [x & ys])

This requires that the function was either defined using defn, or the :arglists metadata supplied explicitly.

Mike Douglas
Superb. Thanks a lot
bugspy.net
+4  A: 

Note, that this really only works for functions defined with defn. It does not work for anonymous functions defined with fn or #().

kotarak
As far as I can see it works for all builtin functions too. For example (:arglists (meta #'+)) or (:arglists (meta #'println))
bugspy.net
kotarak
+2  A: 

Sneaky reflection:

(defn arg-count [f] (let [m (first (.getDeclaredMethods (class f))) p (.getParameterTypes m)] (alength p)))

whocaresanyway
Doesn't work on macros
bugspy.net