Closed gafter closed 1 year ago
Oh, the hash of a type probably isn't stable between julia runs, as it is based on object identity. Which means that an object with a precomputed hash that involves the hash of a type likely will not get the same hash code as another "equivalent" object created in a different run of julia.
It actually is stable within a particular build of Julia it seems.
This might be better:
# compute the hash of any given type by hashing the fully qualified name of that
# type. But do it only once, and cache the result in a generated function.
@generated function _hashed_type_name(x::Type{T}) where {T}
hash(string(T))
end
I wonder how Union types decide what order to print their members in.
julia> Union{Union{A{String}, A{Int}}, Int}
Union{Int64, A{Int64}, A{String}}
julia> Union{Int64, A{Int64}, A{String}}
Union{Int64, A{Int64}, A{String}}
@NHDaly points out that can change even during a single run due to aliasing. This, then:
@generated function _hashed_type_name(x::Type{T}) where {T}
iobuf = IOBuffer()
show(IOContext(iobuf, :compact => false), T) # This IOContext avoids alias search.
type_string = String(resize!(iobuf.data, iobuf.size))
hash(type_string)
end
julia> module A; struct B; x; end; end
Main.A
julia> Base.hash(A.B)
0xedeca5aeea4dd690
julia> module A; struct B; x; end; end
WARNING: replacing module A.
Main.A
julia> Base.hash(A.B)
0x11bcb3aac1326f85
We have https://github.com/JuliaServices/AutoHashEquals.jl/pull/44 to address this for clients who care.
hashing a type is not fast. That's why some people cache it in a static map. This code should either avoid hashing a type, or should store it in a static map.