# Why isn't isequal(x,y) = hash(x) == hash(y)

**URL:** <https://discourse.julialang.org/t/why-isnt-isequal-x-y-hash-x-hash-y/8300>\
**Category:** General Usage\
**Created:** [January 12, 2018, 3:23am UTC](https://discourse.julialang.org/t/why-isnt-isequal-x-y-hash-x-hash-y/8300 "2018-01-12T03:23:37Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jandehaan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jandehaan/32/6805_2.png) [@jandehaan](https://discourse.julialang.org/u/jandehaan)\
**Post date:** [January 12, 2018, 3:23am UTC](https://discourse.julialang.org/t/why-isnt-isequal-x-y-hash-x-hash-y/8300/1 "2018-01-12T03:23:37Z")

</div>

From the 0.6.2 documentation

> isequal is the comparison function used by hash tables (Dict). isequal(x,y) must imply that hash(x) == hash(y).
> 
> This typically means that if you define your own == function then you must define a corresponding hash (and vice versa). Collections typically implement isequal by calling isequal recursively on all contents.

Based on the first sentence you’d think that the default implementation of isequal is

> isequal(x,y) = hash(x) == hash(y)

But the various implementations in Base do something completely different. Why is that?

Also, the documentation says _“if you define your own **==** function then you must define a corresponding hash”_.   
  
Did it mean to say _“if you define your own **isequal** function then you must define a corresponding hash”_?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [January 12, 2018, 3:40am UTC](https://discourse.julialang.org/t/why-isnt-isequal-x-y-hash-x-hash-y/8300/2 "2018-01-12T03:40:06Z")

</div>

Because hash collisions exist.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [January 12, 2018, 4:09am UTC](https://discourse.julialang.org/t/why-isnt-isequal-x-y-hash-x-hash-y/8300/3 "2018-01-12T04:09:52Z")

</div>

> [@jandehaan](#):
>
> Equal is the comparison function used by hash tables (Dict). isequal(x,y) must imply that hash(x) == hash(y).

Consider the example

```julia
julia> immutable Foo
       x::Int
       end

julia> Base.hash(ff::Foo) = ff.x % 2 

julia> Base.isequal(ff::Foo, gg::Foo) = ff.x == gg.x

```

( you should actually overload `Base.hash(x, h::UInt)::UInt` but for this example)

So if they are equal then they will have the same hash.  
We have met the requirement.  
equals implies hashes match.

But the reverse does not hold.  
Not everything with the same hash is equal.

```julia

julia> a = Foo(2)
Foo(2)

julia> b = Foo(2)
Foo(2)

julia> c = Foo(4)
Foo(4)

julia> isequal(a,b)
true

julia> isequal(a,c)
false

julia> hash(a)==hash(b)
true

julia> hash(a)==hash(c)
true

```
