Hi!

Il giorno mercoledì 19 agosto 2009 21:16:35 UTC+2, John Harrop ha scritto:
>
> On Wed, Aug 19, 2009 at 10:03 AM, Achim Passen <achim....@gmail.com 
> <javascript:>> wrote:
>
>> Beware! This snippet relies on unexposed details of clojure's current
>> implementation. It might stop working tomorrow, so it's definitely not
>> intended for production use, but it might help with debbuging/exploring.
>
>
> Meanwhile, for declared functions this works:
>
> (map #(if (contains? (set %) '&) [:more (- (count %) 2)] (count %)) 
> (:arglists ^#'foo))
>
> giving results like:
>
> (0 2 5 [:more 7])
>
> (in this case for (defn foo ([] nil) ([glorb fuzzle] nil) ([x y z w u] x) 
> ([a b c d e f g & more] more)))
>
> Add this:
>
> (defn accepts-arity [arities arity]
>   (or
>     (contains? (set arities) arity)
>     (and (vector? (last arities)) (>= arity (second (last arities))))))
>
> and you can check if the function accepts a particular arity. (This 
> expects "arities" in the format output by my map expression. In particular, 
> a list of numerical arities and possibly a [:more n] entry, which must be a 
> vector and must be the last item in the list if present, and n must be the 
> number of required parameters for the "& more" overload.)
>
> Wrap it all up with two macros:
>
> (defmacro fn-arities [fn-name]
>   `(map (fn [x#] (if (contains? (set x#) '&) [:more (- (count x#) 2)] 
> (count x#))) (:arglists ^#'~fn-name)))
>
> (defmacro fn-accepts-arity [fn-name arity]
>   `(accepts-arity (fn-arities ~fn-name) ~arity))
>
> user=> (fn-accepts-arity foo 8)
> true
> user=> (fn-accepts-arity foo 6)
> false
> user=> (fn-accepts-arity reduce 2)
> true
> user=> (fn-accepts-arity reduce 3)
> true
> user=> (fn-accepts-arity reduce 4)
> false
> user=> (fn-arities map)
> (2 3 4 [:more 4])
>
> Works for macros, too:
>
> user=> (fn-arities fn-arities)
> (1)
> user=> (fn-arities fn-accepts-arity)
> (2)
>
> But, as noted, only works with a name of a declared fn or macro:
>
> user=> (fn-arities #(+ 3 %))
> #<CompilerException java.lang.ClassCastException: clojure.lang.Cons cannot 
> be cast to clojure.lang.Symbol (NO_SOURCE_FILE:110)>
>
> (One thing odd about that:
>
> user=> (class '#(+ 3 %))
> clojure.lang.PersistentList
>
> not Cons. Hmm.)
>
> It also doesn't work with local, named functions, either using let or 
> using letfn, even if (fn name [args] body) is used and not (fn [args] body):
>
> user=> (let [x (fn [a] (+ 3 a))] (fn-arities x))
> #<CompilerException java.lang.Exception: Unable to resolve var: x in this 
> context (NO_SOURCE_FILE:117)>
> user=> (let [x (fn x [a] (+ 3 a))] (fn-arities x))
> #<CompilerException java.lang.Exception: Unable to resolve var: x in this 
> context (NO_SOURCE_FILE:118)>
> user=> (letfn [(x [a] (+ 3 a))] (fn-arities x))
> #<CompilerException java.lang.Exception: Unable to resolve var: x in this 
> context (NO_SOURCE_FILE:119)>
>
>
It's a *very* old thread, but is there any news about this? I mean, is 
there a way to find the list of accepted arities of an anonymous function, 
without trying them all and catching the exception?

Thanks!
 

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to