Details
-
Type:
Defect
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: Release 1.4
-
Fix Version/s: None
-
Component/s: None
-
Labels:None
-
Patch:Code and Test
-
Approval:Not Approved
Description
The doc string for hash states that it defines a hash code function that is consistent with =, but for java.math.BigInteger hash is not consistent with =.
user=> (apply = [(Long. -1) -1N (biginteger -1)]) true user=> (map hash [(Long. -1) -1N (biginteger -1)]) (0 0 -1) user=>
It is possible to have a PHM with two key/value pairs where the keys are equal, and the hash codes are different:
user=> (assoc clojure.lang.PersistentHashMap/EMPTY (biginteger -1) :oops! -1N :one)
{-1N :one, -1 :oops!}
The expected behavior is the same as PersistentArrayMap, which does not have this issue, because it does not hash its keys:
user=> (assoc clojure.lang.PersistentArrayMap/EMPTY (biginteger -1) :oops! -1N :one)
{-1 :one}
This same misbehavior also occurs for Doubles and Floats:
thalia.core=> (apply = [(Float. 1e9) (Double. 1e9)]) true thalia.core=> (map hash [(Float. 1e9) (Double. 1e9)]) (1315859240 1104006501)
That leads to the same difference in array-map and hash-map behavior as above for BigInteger and BigInt.
Attachments
Activity
Andy Fingerhut
made changes -
| Field | Original Value | New Value |
|---|---|---|
| Attachment | clj-1036-hasheq-for-biginteger-patch-v1.txt [ 11524 ] |
Andy Fingerhut
made changes -
| Patch | Code and Test [ 10002 ] |
Stuart Halloway
made changes -
| Approval | Screened [ 10004 ] |
Rich Hickey
made changes -
| Approval | Screened [ 10004 ] | Not Approved [ 10008 ] |
Andy Fingerhut
made changes -
| Attachment | clj-1036-hasheq-for-biginteger-patch-v2.txt [ 11674 ] |
Andy Fingerhut
made changes -
| Attachment | clj-1036-hasheq-for-biginteger-patch-v1.txt [ 11524 ] |
Andy Fingerhut
made changes -
| Approval | Not Approved [ 10008 ] | Vetted [ 10003 ] |
Andy Fingerhut
made changes -
| Description |
The doc string for {{hash}} states that it defines a hash code function that is consistent with {{=}}, but for java.math.BigInteger {{hash}} is not consistent with {{=}}.
{noformat} user=> (apply = [(Long. -1) -1N (biginteger -1)]) true user=> (map hash [(Long. -1) -1N (biginteger -1)]) (0 0 -1) user=> {noformat} It is possible to have a PHM with two key/value pairs where the keys are equal, and the hash codes are different: {noformat} user=> (assoc clojure.lang.PersistentHashMap/EMPTY (biginteger -1) :oops! -1N :one) {-1N :one, -1 :oops!} {noformat} The expected behavior is the same as PersistentArrayMap, which does not have this issue, because it does not hash its keys: {noformat} user=> (assoc clojure.lang.PersistentArrayMap/EMPTY (biginteger -1) :oops! -1N :one) {-1 :one} {noformat} |
The doc string for {{hash}} states that it defines a hash code function that is consistent with {{=}}, but for java.math.BigInteger {{hash}} is not consistent with {{=}}.
{noformat} user=> (apply = [(Long. -1) -1N (biginteger -1)]) true user=> (map hash [(Long. -1) -1N (biginteger -1)]) (0 0 -1) user=> {noformat} It is possible to have a PHM with two key/value pairs where the keys are equal, and the hash codes are different: {noformat} user=> (assoc clojure.lang.PersistentHashMap/EMPTY (biginteger -1) :oops! -1N :one) {-1N :one, -1 :oops!} {noformat} The expected behavior is the same as PersistentArrayMap, which does not have this issue, because it does not hash its keys: {noformat} user=> (assoc clojure.lang.PersistentArrayMap/EMPTY (biginteger -1) :oops! -1N :one) {-1 :one} {noformat} This same misbehavior also occurs for Doubles and Floats: {noformat} thalia.core=> (apply = [(Float. 1e9) (Double. 1e9)]) true thalia.core=> (map hash [(Float. 1e9) (Double. 1e9)]) (1315859240 1104006501) {noformat} That leads to the same difference in array-map and hash-map behavior as above for BigInteger and BigInt. |
Rich Hickey
made changes -
| Approval | Vetted [ 10003 ] | Not Approved [ 10008 ] |