Complex{Float64} <: Complex{Real} is false. Intended or potential inconsistency?

question

#1

On Julia 1.0.2

julia> Float64 <: Real
true

as it should be but

julia> Complex{Float64} <: Complex{Real}
false

Mathematically speaking, this should be true as well but, I guess, Julia has to deal with types of a more general nature, which probably makes it difficult to determine whether one composite type is a subset (or what is the correct term for such things) of another type.

If the current behavior is intended, how to implement type assertion in situations like

function foo(z::Complex{Real})
    return sqrt(z)
end

to make sure that both foo(0.0im) and foo(0im) work in the same way as for z::Real with foo(0.0) and foo(0)?


#2

You need Complex{<:Real}. That’s due to type invariance, while what you want is covariance (look for these keywords in the manual).


#3

I have wondered why Julia has this limitation. Is it for performance or just to reduce complexity?


#4

It’s not a limitation, its a property. It’s deeply related to everything in the language and basically everything has to be done differently if you change this so it’s hard to say what exactly it is for.

Of course someone might be able to comment on the original reason this is selected, though finding an alternative for that particular reason will not be enough to make such change at this point.


#5

Thanks a bunch! It looks like, indeed, I needed type covariance all the way and just coincidentally didn’t run into the same problem before. The funny part is I did read that part in the manual and it made sense but somehow syntactic details didn’t register.


#6

It’s absolutely critical for performance, as I explained in another post.