Fork me on GitHub
#clojure-dev
<
2017-11-07
>
slipset08:11:35

This threw me off the other day

slipset08:11:38

09:43 $ clj
Clojure 1.8.0
(defmulti foo :bar)
(defmethod foo :qix [quux znoot] (println 'hi))
#'user/foo
user=> #object[clojure.lang.MultiFn 0x205d38da "clojure.lang.MultiFn@205d38da"]
user=> (foo {:bar :qix})
ArityException Wrong number of args (1) passed to: user/eval5/fn--6  clojure.lang.AFn.throwArity (AFn.java:429)
user=>

slipset08:11:05

Albeit in a more convoluted setting.

slipset08:11:21

Reading through some code, I see that defmethod does amongst other things a call (fn ~@fn-tail) which gives us a function named, in my example user/eval5/fn--6

slipset08:11:41

If we change the call to fn to be (fn ~multifn ~@fn-tail) the error becomes:

slipset08:11:45

user=> (defmulti foo :bar)
(defmethod foo :qix [quux znoot] (println 'hi))
(foo {:bar :qix})#'user/foo
user=> #object[clojure.lang.MultiFn 0x4e928fbf "clojure.lang.MultiFn@4e928fbf"]
user=>
ArityException Wrong number of args (1) passed to: user/eval5/foo--6  clojure.lang.AFn.throwArity (AFn.java:429)
user=>

slipset08:11:24

Which at least gives the user a clue. Would a ticket be in order ofr this?

slipset08:11:43

Another way to get to this would be to let AFn have a specific name (which would default to getClass().getSimpleName() and have MultiFn set the name of the AFn when addMethod is called.

slipset08:11:16

The latter approach leads to:

slipset08:11:37

Clojure 1.8.0
user=> (defmulti foo :bar)
(defmethod foo :qix [quux znoot] (println 'hi))
(foo {:bar :qix})#'user/foo
user=> #object[clojure.lang.MultiFn 0x4e928fbf "clojure.lang.MultiFn@4e928fbf"]
user=>
ArityException Wrong number of args (1) passed to: foo  clojure.lang.AFn.throwArity (AFn.java:441)
user=>

slipset08:11:56

Problem here is that we loose the ns of the function.