Suppose I define a number type T
for which order comparison is not meaningful: <(x::T, y::T)
doesn’t make any mathematical sense, because T
actually contains a set. There are good reasons why I’m doing this, see SparseConnectivityTracer.jl, but that’s not the topic of today.
My problem is that I still want to allow control flow with ifelse
. In my scenario, ifelse(x < y, a, b)
should ignore the comparison result and just return some function f(a, b)
(essentially taking both branches at once).
How bad is it if I define something like the following?
struct T <: Real
s::Set{Int}
end
f(a::T, b::T) = T(union(a.s, b.s))
Base.:<(x::T, y::T) = missing
Base.ifelse(::Missing, a::T, b::T) = f(a, b)
It works:
julia> a, b = T(Set([1, 2, 3])), T(Set([3, 4, 5]));
julia> ifelse(a < b, a, b)
T(Set([5, 4, 2, 3, 1]))
But I’m afraid it might lead to invalidations or other bad behavior. How criminal is it to break the convention that <
must return a Bool
?