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

0 votes
in ClojureScript by
Currently {{compare}} (for any non-CLJS IComparable) types only accepts primitives (numbers, bool, string, array) and forwards them to {{goog.array.defaultCompare}} (which is just a {{ return a > b ? 1 : a < b ? -1 : 0 }} ).

Though, the standard defines anything with a {{valueOf}} can be compared:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Relational_operators

since {{valueOf}} should return one of these primitves. Ie this works:


(let [x0 #js{:x 1, :valueOf #(-> 1)}
      x1 #js{:x 2, :valueOf #(-> 2)}
      dc garr/defaultCompare]
  (list (dc x0 x1) (dc x1 x0) (dc x1 x1)))


We should allow this, ie. instead of:


:else
(if (and (or (string? x) (array? x) (true? x) (false? x))
         (identical? (type x) (type y)))
     (garray/defaultCompare x y)
     (throw (js/Error. (str "Cannot compare " x " to " y))))


do a:

(if (and (or (string? x) (array? x) (true? x) (false? x)
             (and (js-in "valueOf" x) (js-in "valueOf" y)))
         (identical? (type x) (type y)))
      (garr/defaultCompare x y)
      (throw (js/Error. (str "Cannot compare " x " to " y))))


We should also give {{js-in}} a boolean tag.

1 Answer

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJS-2479 (reported by aralo)
...