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

0 votes
in Collections by
CLJ-1242 partially fixed = throwing an exception when comparing with sorted collections, but there are still cases where this will throw.

(= {:todos 1} (sorted-map 1 2))

ClassCastException java.lang.Long cannot be cast to clojure.lang.Keyword  clojure.lang.Keyword.compareTo (Keyword.java:114)

Some of the tests in the original patch on CLJ-1242 also still throw exceptions. - https://dev.clojure.org/jira/secure/attachment/12084/0001-fix-for-CLJ-1242-tests.patch.

Note that this is not symmetrical, the reverse doesn't throw.

(def a {:todos 1})
(def b (sorted-map 1 2))

(= a b)
=> <throws>
(= b a)
=> false

3 Answers

0 votes

Comment made by: desk@danielcompton.net

This issue also exists in ClojureScript (which is where we first discovered it).

0 votes

Comment made by: steveminer@gmail.com

The rejected fix for CLJ-1242 that protected entryAt from ClassCastException would have fixed this as well. The root of the issue is that the exception can come from checking keys so it makes sense to fix it there. The accepted fix for CLJ-1242 protected only the = test with the sorted-map first. The more basic key access question was punted. I expect this to work:

`(= (get (sorted-map 1 2) :a :missing) :missing)`

I think it's worth taking another look at entryAt. Most users would expect the following to succeed:

`(every? (fn [create] (= (get (create 1 2) :a :missing) :missing)) [hash-map array-map sorted-map])`

If there's a performance concern, then the restriction on testing keys should be documented.

0 votes
Reference: https://clojure.atlassian.net/browse/CLJ-2325 (reported by desk@danielcompton.net)