Welcome! Please see the About page for a little more info on how this works.

0 votes
in Errors by

The error messages of defmulti are at the moment not as helpful as they could be under certain circumstances. Calling this multi method with a lazy seq as it's dispatch argument raises the following exception:

(defmulti test-multi identity)
(defmethod test-multi 1 [arg] true)

(test-multi (map identity [:x]))
;=> java.lang.IllegalArgumentException: No method in multimethod 'test-multi' for dispatch value: clojure.lang.LazySeq@3c6f1187

Sometimes it would be useful to actually see which values are in the lazy seq being dispatched on. A better error message could look like
this for example:

(test-multi (map identity [:x])) ;=> java.lang.IllegalArgumentException: No method in multimethod 'test-multi' for dispatch value (:x) of class clojure.lang.LazySeq

This patch addresses this issue by formatting the dispatch value via pr-str and printing the class before it is passed to the exception constructor. The same is also done for the methods in MultiFn.java that throw a dispatch value as part of their exception message.

4 Answers

0 votes

Comment made by: bronsa

What if the value is infinite lazy-seq?

0 votes

Comment made by: r0man

Nicola, I forgot those. But I think infinite sequences could be handled with:

(set! *print-length* 10)

I'll try it out and will update the patch later.

Any other edge cases in mind?

0 votes
_Comment made by: r0man_

After having read "Controlling run-away trains, onions, and exercise
bikes" [1] I now bind *print-length* and *print-size* when building
the error message. This helps when not being able to dispatch on this
for example:

(test-multi (let [x (atom 0)] (reset! x {:deeper x})))

However I'm not sure if this helps in the following case, where
dispatching would fail on an infinite seq.

(test-multi (iterate inc 0))

The above doesn't terminate in Clojure 1.6.0, nor does it when binding
*print-length* like the attached patch does.

[1] http://blog.n01se.net/blog-n01se-net-p-85.html
0 votes
Reference: https://clojure.atlassian.net/browse/CLJ-1394 (reported by r0man)