Clojure

Util/hasheq should be hashing a BigInteger to the same values as Long, and BigInt

Details

  • Type: Defect Defect
  • Status: Open Open
  • Priority: Major 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.

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 -
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 ]

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated: