Comparing Mutable Structs

dear wizards—is this intended behavior?

julia> mutable struct S; x::Int; end#struct##

julia> v= [ S(1), S(2) ]
2-element Array{S,1}:
 S(1)
 S(2)

julia> v==deepcopy(v)   ## only when v is mutable
false

julia> v==copy(v)
true

if so, how do I check that a deepcopy() result has identical content to its original?

advice appreciated.

regards,

/iaw

This is fully intended. You should note that v = S(1); v != deepcopy(v) and S(1) != S(1) so comparing the object with != won’t be useful.

By definition you can check the serialization being the same, though you should really specify what do you actually want to do. Writing test for deepcopy?

uggh. I should have started simpler. My premise was wrong. I have a worse lack of understanding mutables vs const than I thought. It does way more than just make contents unchangeable.

julia> mutable struct S; x::Int; end#struct##

julia S(1) == S(1)
false

I had known that S(1) === S(1), because the left object is distinguishable from the right object. The L creates an object different from the R, so assigning to one would not be the same as assigning to the other.

So what is S(1) == S(1) actually testing that is different from S(1) === S(2) with mutable structs?

julia> struct R; x::Int; end#struct##

julia R(1) == R(1)
true

Similar question here for immutable. Again, == and === seem to do the same thing.

It is a virtue when programming languages give the naively expected results…

By default, nothing. You can check this yourself. Just do:

julia> mutable struct S; end

julia> @edit S() == S()

which shows that the default implementation is:

## generic comparison ##

==(x, y) = x === y

The difference is that you can overload == to mean whatever you want for a particular type.

There’s no way for Julia to know exactly what == equality means to you for some new type, so by default it does the most conservative thing and only declares two mutable structs as equal if they are truly indistinguishable.

And note that if you do overload Base.:(==), you should also overload Base.hash (except you should overload the two-argument version, as noted in https://docs.julialang.org/en/stable/stdlib/base/#Base.hash); see https://docs.julialang.org/en/stable/stdlib/base/#Base.isequal-Tuple{Any,Any}.

Related reading: https://github.com/JuliaLang/julia/issues/4648

even C knows this for structs! :wink:

Are you sure about that?

I stand corrected.

It just seems strange that if I can write a=b, I should be able to write a==b and (except for NaN type cases) receive true.

regards,

/iaw

Note that this IS actually the case in julia.

this is what you get if you allow idiots onto discourse forums…

PS: fortunately, my turning red is not visible over the net.

The new links for these are:
https://docs.julialang.org/en/v1/base/base/#Base.hash
https://docs.julialang.org/en/v1/base/base/#Base.isequal