Immutables automatically have value-based hashing defined for them. That's a dangerous default for mutable values since it makes it easy to stick something in a dict, then mutate it, and "lose it", e.g.:
type Mutable x::Int end Base.hash(m::Mutable, h::UInt) = hash(m.x, h + (0x17d88030d571c6e3 % UInt)) ==(m1::Mutable, m2::Mutable) = m1.x == m2.x julia> m = Mutable(0) Mutable(0) julia> d = Dict() Dict{Any,Any} with 0 entries julia> d[m] = "here" "here" julia> m.x = 1 1 julia> d[m] ERROR: KeyError: Mutable(1) not found in getindex at dict.jl:695 julia> d Dict{Any,Any} with 1 entry: Mutable(1) => "here" On Thu, Jul 16, 2015 at 12:35 PM, Seth <catch...@bromberger.com> wrote: > > > On Thursday, July 16, 2015 at 9:25:01 AM UTC-7, Matt Bauman wrote: >> >> On Thursday, July 16, 2015 at 12:19:25 PM UTC-4, milktrader wrote: >>> >>> Also, back to the OP question, is the correct solution to simply define >>> >>> Base.hash(f::Foo) = f.x >>> >> >> No, I'd define Base.hash(f::Foo) = hash(f.x, 0x64c74221932dea5b), where >> I chose the constant by rand(UInt). This way it won't collide with other >> types. I really need to spend a bit more time with my interfaces chapter >> and add this info there. >> >> > How would you do this (in a performant way) for a type that has two > internal values? That is, I have > > immutable Foo{T} > x::T > y::T > end > > > Obviously, the hash should be based on both values, right? I could do > > Base.hash(f::Foo) = hash(hash(f.x, f.y), 0x64c74221932dea5b) > > But that calls hash twice. (Is this even necessary with immutables?) > >