Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hash instability in Julia composite types

Tags:

julia

In Julia, composite types with at least one field that have identical values hash to different values. This means composite types don't function correctly if you use them as dictionary keys or anything else that is dependent on the hashed value. This behavior is inconsistent with the behavior of other types, such as Vector{Int} as well.

More concretely,

vectors of non-composite types that are different objects but have identical values hash to the same value:

julia> hash([1,2,3])==hash([1,2,3])
true

composite types with no fields hash to the same value:

julia> type A end
julia> hash(A())==hash(A())
true

composite types with at least one field hash to different values if they're different objects that have the same value:

julia> type B
           b::Int
       end
julia> hash(B(1))==hash(B(1))
false

however, the same object maintains its hash even if the underlying values change:

julia> b=B(1)
julia> hash(b)
0x0b2c67452351ff52

julia> b.b=2;
julia> hash(b)
0x0b2c67452351ff52

this is inconsistent with the behavior of vectors (if you change an element, the hash changes):

julia> a = [1,2,3];
julia> hash(a)
0xd468fb40d24a17cf

julia> a[1]=2;
julia> hash(a)
0x777c61a790f5843f

this issue is not present for immutable types:

julia> immutable C
           c::Int
       end
julia> hash(C(1))==hash(C(1))
true

Is there something fundamental driving this behavior from a language design perspective? Are there plans to fix or correct this behavior?

like image 897
Ben Hamner Avatar asked Dec 26 '14 19:12

Ben Hamner


1 Answers

I'm not a Julia language designer, but I'l say this sort of behavior is not surprising when comparing mutable and immutable values. Your type B is mutable: it's not entirely obvious that two instances of it, even if they have the same value for field b, should be considered equal. If you feel like this should be the case, you are free to implement a hash function for it. But in general, mutable objects have independent identities. Immutable entities, like C are impossible to tell apart from each other, therefore it makes sense for them to obey structural hashing.

Two bank accounts that happen to have $5 in them are not identical and probably shouldn't hash to the same number. But two instances of $5 are impossible to distinguish from each other.

like image 189
Sebastian Good Avatar answered Oct 13 '22 00:10

Sebastian Good