OK, I think I got it:

type Foo{T}
  x::T
  y::T
end

Base.hash(f::Foo) = hash(f.x, hash(f.y, pair_seed))




On Thursday, July 16, 2015 at 9:46:12 AM UTC-7, Matt Bauman wrote:
>
> Goodness, I'll get this right one of these times.  Sorry for spouting off 
> so much disinformation!  I'll try to make up for it by adding more examples 
> to the documentation.
>
> const _foo_seed = UInt === UInt64 ? 0x64c74221932dea5b : 0x80783eb4
> Base.hash(f::Foo, h::UInt) = hash(f.x, h += _foo_seed)
>
> The canonical hash function to define is the one that takes a second 
> `UInt` argument.  Here's what the help has to say about hashing multiple 
> values: "New types should implement the 2-argument form, typically  by 
> calling the 2-argument `hash` method recursively in order to mix hashes of 
> the contents with each other (and with `h`)".  And that's exactly how most 
> base functions do it.
>
> On Thursday, July 16, 2015 at 12:35:25 PM UTC-4, Seth 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?)
>>
>>

Reply via email to