When should things be equal?

There is some useful (at least for me) discussion between @marius311 and I on this issue about when equality should hold between things.

It was a little surprising to me that in general A == B between two arrays always follows from all(A .== B) regardless of the types of A and B. Some examples of this are:

julia> [1 2 3] == [1, 2, 3]'
true

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

julia> using StaticArrays

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

While I can see where this would be a useful property, it makes things tricky when trying to implement equality for something like ComponentArrays. It seems obvious that ComponentArray(a=1, b=2) != ComponentArray(x=1, y=2). However the whole point of ComponentArrays is that they need to work in any library that expects an AbstractArray. Since it seems to be part of the contract of AbstractArrays that A == B holds when the the elements of A and B are equal, I am hesitant to break from that. I just don’t have any way of guaranteeing that, say, DifferentialEquations.jl or Optim.jl isn’t using A == B under the hood somewhere. And since hash(A) == hash(B) needs to hold whenever A == B, we can’t just implement equality between two dissimilar ComponentArrays as a separate thing.

I assume equality between arrays (and things in general) has been discussed somewhere before. I would be curious to see the original rationale behind A == B for arrays when their elements are equal.

2 Likes

I only found this comment but probably there is a better discussion somewhere else.

1 Like

I think the policy is that both keys and values need to be equal for two AbstractArrays to be equal:

julia> OffsetArray([1,2,3], 2) == [1,2,3]
false

julia> OffsetArray([1,2,3], 0) == [1,2,3]
true
6 Likes

Ah, that makes sense. Especially since this is how hash on AbstractArrays is implemented (of course, that doesn’t work for arrays whose keys aren’t LinearIndices or CartesianIndices like most of the symbolic-indexed arrays like ComponentArrays, LabelledArrays, and such). So perhaps the correct way to handle this is to make them not equal. I guess that means I’ll have to trust that solvers and libraries that people are using ComponentArrays for are using == correctly.