Now you might say that complex numbers should actually work on the one-point compactification (such that Complex(Inf) == Complex(0,Inf)==-Complex(Inf) and Complex(0*Inf) === Complex(NaN) === Complex(Inf)+Complex(Inf)) but this breaks transitivity of Inf == Complex(Inf) == Complex(-Inf) == -Inf != Inf and would probably be quite annoying/slow to code.
This is the case even though 0==false. Arithmetic in julia is almost never well defined modulo isequal or ==. You need to compare typeof(x)==typeof(y) && isequal(x,y) in order to get well-definedness. Excepting weird guys like BigInt and BigFloat, you can also check ===. User-defined notions of equality that allow objects of different types to be equal are common in many languages, e.g. php or javascript (ok, I have some beef with this core decision, but for better or worse 1==1.0 is gonna stay and we have to live with it).
Let’s see what the two versions you had boil down to:
The definition of *(::Bool, ::Number) has the following comment attached to it:
# make `false` a "strong zero": false*NaN == 0.0
Since im is a Complex{Bool}, its real part is a “strong zero”, so the product im*Inf will have a zero in the real part. However, if im is converted to any other Complex type before the multiplication with Inf, then the real part will be NaN.
julia> im*Inf
0.0 + Inf*im
julia> (UInt8(1)*im)*Inf
NaN + Inf*im
julia> (im+0)*Inf
NaN + Inf*im
julia> Complex{Float64}(im)*Inf
NaN + Inf*im
My original gut feeling is that im is just the imaginary unit, by which I mean purely imaginary without even a zero real part. Just as a float has no concept of an imaginary component, or complex has no concept of quarternions etc. If it’s purely the imaginary unit there is no zero for multiplication by Inf, and hence there is no NaN.
I suppose I’m just drawing the distinction between an imaginary number and a complex number. Perhaps an improved description for the im documentation might be:
The imaginary unit as a complex number with zero real part.
Maybe the c++ macro is why I think this. But I haven’t checked it’s behaviour associated with Inf and NaN.
The imaginary unit is a complex number. Don’t you think mathematics and implementation align here? Also I actually like that im has a strong real zero, making it behave closer to a mathematical constant than to a measured number.
I’m not a trained mathematician, which might be where there is a difference in terminology.
i is the imaginary unit, which is the unit vector in the imaginary direction. Only tacitly is it an imaginary number. It’s the (non-existent?) difference between 0+1i and just i.