Consider a hierarchy:
(derive ::lchild ::parent)
(derive ::rchild ::parent)
(derive ::gchild ::lchild)
(derive ::gchild ::rchild)
(derive ::ggchild ::gchild)
And a multimethod:
(defmethod mm ::parent [x] nil)
(defmethod mm ::lchild [x] nil)
(defmethod mm ::rchild [x] nil)
(defmethod mm ::gchild [x] nil)
Calling (mm ::ggchild)
should call the method defined for ::gchild
, but it fails, instead:
user=> (mm ::ggchild)
Execution error (IllegalArgumentException) at user/eval224 (REPL:1).
Multiple methods in multimethod 'mm' match dispatch value: :user/ggchild -> :user/lchild and :user/rchild, and neither is preferred
However, the failure is not consistent. The order of methods in the loop in MultiFn::findAndCacheBestMethod
over MultiFn::getMethodTable()
depends on the hashes of the dispatch values (keywords in this case). Therefore, giving the dispatch values different names may give the impression of working correctly. E.g. appending '7' to every keyword "works":
user=> (mm7 ::ggchild7)
nil
A possible solution would be to split the finding bestEntry
and the validation into 2 separate loops.