Why two composite types with all bitstypes members are different if they are defined mutable?

As from the title: I am a bit confused on why two composite types with all bitstypes members are different if they are defined mutable ?

mutable struct Foo
    x::Bool
end
struct Goo
    x::Bool
end

julia> f1 = Foo(true)
Foo(true)
julia> f2 = Foo(true)
Foo(true)
julia> f1 == f2
false
julia> g1 = Goo(true)
Goo(true)
julia> g2 = Goo(true)
Goo(true)
julia> g1 == g2
true

Let me see if I got it while writing this question… the Goo instances do memorize the actual bool value, while the Foo instances memorize only the memory address of them. This memory address is different between f1 and f2.
Still, I would have expected the === operator to fail, while I would have expected == to lookup these memory addresses and look that the actual bit values are the same (true) for both objects… :face_with_spiral_eyes:

== falls back to === by default, it doesn’t recurse into fields automatically. Look into AutoHashEquals.jl if you need/want that.

3 Likes

I think as @Sukera 's said that == falls back to === by default, and because immutable objects is stack allocated (share memory for performance) see this :arrow_down:

julia> g1 |> objectid
0x00000000247a75a3

julia> g2 |> objectid
0x00000000247a75a3

But for mutable objects it is heap allocated (object created don’t share memory) :arrow_down:

julia> f1 |> objectid
0xd8248564904acb41

julia> f2 |> objectid
0x088b6250e182dc49

Which is not the same objects so === and == returns false , But you can overload == with Base.:(==) like this

julia> Base.:(==)(f::Foo, f::Foo) = f.x == f.x

So f1 == f2 returns true.

1 Like