Is this a bug? ``Some([]) != Some([])``

I know that there are a couple of open discussions about how to compare general structs by default.

However for the concrete type Some,

Some([]) == Some([])

should return true, shouldn’t it? But it returns false

Using Julia 1.4.1


EDIT: adding

Base.:(==)(a::Some, b::Some) = a.value == b.value

fixes the problem, however this should be in Base, shouldn’t it?

1 Like

Not all types have == defined — this depends on the use case (if they do, hash should also be defined for that type; see ?==).

Since Some is almost always used as an intermediate wrapper, I don’t see the strong use case for ==.

1 Like

Some is meant to be a transparent wrapper, which indicates that something is definitely not nothing.
as such, I would make it fully transparent, i.e. also == should behave the same

2 Likes

Since Some being a wrapper for objects (not some container type) and both [] and [] not being the same object, one could argue that this definition of equality of Some makes sense.

Maybe Some is more like Ref? Ref has the same behavior. See Make Refs compare equal when their contents are equal by ararslan · Pull Request #31885 · JuliaLang/julia · GitHub and the linked issue for a discussion of the behavior of == and Ref.

My understanding is that Some is meant for code like

function f(x, y, z)
    v = g(x, y) # Union{Nothing,Some}
    if v === nothing
        some_default_value(x, z)
    else
        w = something(v)
    end
end

where hopefully the whole thing is type stable and Some would never leave the function scope, making various optimizations possible. A shortcut mentioned in the docstring ?Some is

w = something(v, some_default_value)

I don’t think that Some wrappers are meant to live on outside the caller, thought that is of course permitted.

Having Some outside the caller is indeed my case currently

considering the container argument, we indeed have

[] == [] # true

so considering Some as a transparent wrapper, we I expect the same for the wrapped values.


Cannot tell about Ref, however the type itself suggests something among references, and okay, [] and [] are two different references. Might be fine to change the definition of equal there…, don’t know.

EDIT: just read into the posted github topic. Indeed the argument seems to be that Ref’s purpose is to mutate the references, i.e. really has reference semantics (mutable struct semantics). However Some is immutable, and really works more like a singleton container.

Also there is this long ranging topic https://github.com/JuliaLang/julia/issues/4648 about enabling == fallback generically for all immutable structs.

One argument there is that the tendency looks right that immutable structs rather should fallback on using ==, however it is best to be decided for each single type on its own.

Some is immutable, and in all programming languages where I used the equivalent data structure (Haskell, Scala, Java), it behaves like a container.
Hence I would speak in favour of using ==, i.e. the current behaviour is more like an inconsistency (or overlooked detail).

2 Likes

Thanks for the small discussion!

I opened this as a change request at Julia github Adding comparison/hashing to Base.Some · Issue #35911 · JuliaLang/julia · GitHub