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=>
It is an implementation detail that multi methods are implemented via anonymous functions. I would expect the error message to at least contain the name of the function that failed, in this case it should have been something like
ArityException Wrong number of args (1) passed to: user/eval5/foo--6 clojure.lang.AFn.throwArity (AFn.java:429)
Several approaches can be taken here:
The first (and simplest) is to change the definition of {{defmethod}} so that the anonymous function gets a name.
This leads to an error message like:
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=>
In addition to this, one could modify Compiler.java to look for the calls to "addMethod"
String prefix = "eval";
if (RT.count(form) > 2) {
Object third = RT.nth(form, 2);
if (third != null &&
"clojure.core/addMethod".equals(third.toString()))
prefix = "multi_fn";
}
ObjExpr fexpr = (ObjExpr) analyze(C.EXPRESSION, RT.list(FN, PersistentVector.EMPTY, form), prefix + RT.nextID());
which would give us error messages like
ArityException Wrong number of args (1) passed to: user/multi-fn5/foo--6 clojure.lang.AFn.throwArity (AFn.java:441)