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

0 votes
in Collections by

VecSeq (as produced by {{(seq (vector-of :int 1 2 3))}}) does not implements equals, hashCode, or hasheq and does not play with any other Clojure collections or sequences appropriately in this regard.

user=> (def rs (range 3)) user=> (def vs (seq (vector-of :int 0 1 2))) user=> rs (0 1 2) user=> vs (0 1 2) user=> (.equals rs vs) true user=> (.equals vs rs) ;; expect: true false user=> (.equiv rs vs) true user=> (.equiv vs rs) true user=> (.hashCode rs) 29824 user=> (.hashCode vs) ;; expect to match (.hashCode rs) 2081327893 user=> (System/identityHashCode vs) ;; show that we're just getting Object hashCode 2081327893 user=> (.hasheq rs) 29824 user=> (.hasheq vs) ;; expect same as (.hasheq rs) but not implemented at all IllegalArgumentException No matching field found: hasheq for class clojure.core.VecSeq clojure.lang.Reflector.getInstanceField (Reflector.java:271)

Approach: Implement Object.hashCode(), Object.equals(), and IHashEq.hasheq() in the primitive vector seq implementation. All of these leverage the prim vec seq itself rather than the underlying prim vec as it was quite a big simpler. The hasheq() impl calls Murmur3/hashOrdered, which takes an Iterable, so Iterable was also implemented using an iterator over the seq.

Some existing tests were expanded to include coverage of the primitive vec seq.

Patch: clj-1364.patch

4 Answers

0 votes
by

Comment made by: jafingerhut

Maybe this is a separate issue, but (.equals (vector-of :long 0 1 2) (range 3)) is also false (i.e. without calling seq on the return value of vector-of).

0 votes
by

Comment made by: alexmiller

Same issue, and is fixed by the patch.

0 votes
by

Comment made by: jafingerhut

Excellent. Sorry, I had not read the new tests in the patch carefully enough to see that this is covered there. Good to know.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-1364 (reported by alexmiller)
...