Julia: isequal and hash are incompatible for UniformScaling

Created on 15 Apr 2020  路  5Comments  路  Source: JuliaLang/julia

julia> isequal(diagm(ones(3)), I)
true

julia> isequal(diagm(ones(4)), I)
true

julia> hash(I)
0x6bd2535d045989b2

julia> hash(diagm(ones(4)))
0x6ba2635b5ca237d8

julia> hash(diagm(ones(3)))
0xf728e5a95d43274d

This is because isequal on UniformScaling is not defined and dispatches to the generic method

julia> @which isequal(diagm(ones(3)), I)
isequal(x, y) in Base at operators.jl:123

which calls ==:

https://github.com/JuliaLang/julia/blob/b37cc3d7c03d0496c65431d621f5d6b7939f8089/base/operators.jl#L123

It seems isequal on UniformScaling has to be defined manually.

A more fundamental solution may be to define isequal in terms of the identity === by default. It seems brittle to define a function with strict semantics (isequal) in terms of the one with weaker semantics (==). (Though this is probably impossible to do within 1.x.)

hashing linear algebra minor change

Most helpful comment

Triage agrees that I(n) == I should not be true, so now we "just" need a PR to change this.

All 5 comments

The fundamental issue is that == is non-transitive in the presence of I which is a bad situation:

julia> I(3) == I == I(4)
true

julia> I(3) == I(4)
false

The best solution is unclear, however. It seems that it's either this or make I(n) == I false.

I want to slate this for fixing in 1.6 since this is the only example of equality being non-transitive that I'm aware of.

Triage agrees that I(n) == I should not be true, so now we "just" need a PR to change this.

Once there's a PR, we'll need a PkgEval run.

While I think it's probably right to change the behavior here, the discussion reminds me that there are some more general challenges associated with the "x==y implies hash(x) == hash(y)" orthodoxy https://github.com/JuliaParallel/DistributedArrays.jl/issues/4#issuecomment-89590255

Was this page helpful?
0 / 5 - 0 ratings