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

+1 vote
in ClojureScript by

The conflict test in cljs.core/-prefer-method seems to be backward, which causes an error if prefer-method is used consistently multiple times (e.g., on reloading code in a repl).

Here's a minimal reproduction of the problem. Though the hierarchy and methods are trivial here, the same problem occurs when there is genuine ambiguity that prefer-method addresses. Note that the message indicates the reversal of preference relative to the documentation for prefer-method. (We want :a prefered to :b here but the message indicates the opposite.)

(def tmph (make-hierarchy))
(defmulti fooz (fn [a b] (keyword b)) :hierarchy #'tmph)
(defmethod fooz :a [a b] a)
(defmethod fooz :b [a b] b)
(prefer-method fooz :a :b)
;=> {:parents {}, :descendants {}, :ancestors {}}
(prefer-method fooz :a :b)
;;  
;; Execution error (Error) at (<cljs repl>:1).
;; Preference conflict in multimethod 'cljs.user/fooz': :b is already preferred to :a
;; :repl/exception!

Run with clj -M -m cljs.main --repl-env node using ClojureScript 1.10.914 in a clean install with the uberjar built from master (at that time).

The problem appears to be that the first two arguments to prefer* are reversed in:

(when (prefers* dispatch-val-x dispatch-val-y prefer-table)
  (throw (js/Error. (str "Preference conflict in multimethod '" name "': " dispatch-val-y
                         " is already preferred to " dispatch-val-x))))

(Line 11356 core.cljs in the definition of MultiFn.) Here the call was to make x preferred to y which should be consistent.

Thanks!

1 Answer

0 votes
by
...