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 ==
:
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.)
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
Most helpful comment
Triage agrees that
I(n) == I
should not be true, so now we "just" need a PR to change this.