Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

real(Number) -> Int #27285

Open
ettersi opened this issue May 28, 2018 · 7 comments
Open

real(Number) -> Int #27285

ettersi opened this issue May 28, 2018 · 7 comments
Labels
maths Mathematical functions types and dispatch Types, subtyping and method dispatch

Comments

@ettersi
Copy link
Contributor

ettersi commented May 28, 2018

I would have expected real(Number) -> Real, but instead I got real(Number) -> Int. One can argue whether real(Number) -> Real is truly the right definition, but clearly real(Number) -> Int makes no sense.

The problem is caused by the following three lines:

julia/base/complex.jl

Lines 108 to 110 in cfca311

real(T::Type) = typeof(real(zero(T)))
real(::Type{T}) where {T<:Real} = T
real(::Type{Complex{T}}) where {T<:Real} = T

@ViralBShah
Copy link
Member

Can you provide a code snippet of exactly what you are tried, and what you got?

@fredrikekre
Copy link
Member

julia> real(Number)
Int64

@ettersi
Copy link
Contributor Author

ettersi commented May 28, 2018

fredrikekre provided the obvious answer, but I assume you were asking in what context I discovered this issue. I am currently working on a LogNumber type that stores a floating point number as sign times logarithm of absolute value to avoid over-/underflow, i.e.

type LogNumber{S,L} <: Number
    sign::S
    logabs::L
end

Base.convert(::Type{<:LogNumber}, x::LogNumber) = x
Base.convert(::Type{T}, x::LogNumber) where {T <: Number} = convert(T,x.sign) * exp(convert(real(T), x.logabs))

I then called broadcast(f,v) with arguments such that it should have returned Vector{LogNumber}, but somehow broadcast allocated a Vector{Number} instead. Calling setindex! on this vector called convert(::Type{Number}, ::LogNumber} which in turn called convert(real(Number), x.logabs) == convert(Int, x.logabs) which resulted in an InexactError().

Unfortunately, I did not manage to construct a MWE for the broadcast call, and in any case there are things which are at least dubious in the above code, but the point remains that real(Number) -> Int seems wrong, and debugging would have been easier for me if either real(Number) -> Real or real(Number) -> Error().

@martinholters
Copy link
Member

I agree that either returning Real or throwing seem better than the current definition. In general, calling real on an abstract type is suspicious. The docstring says: "Return the type that represents the real part of a value of type T". For an abstract type, there is no way of knowing. After all, one could define a new subtype of T any moment. In this particular case, Real might be a reasonable upper bound, but surely, there are valid exceptions. It's a bit like the dreaded promote_op. (BTW, Base.promote_op(real, Number) gives Number.)

That said, your convert definition likely should convert(T, ...) at the end to be sure to return a T , thereby circumventing the problem in this particular case. And, of course, convert(Number, ::LogNumber) should be a no-op.

@JeffBezanson
Copy link
Member

It would be nice to remove zero(Number) === 0 (and one(Number), and similar for other abstract types). That's what's causing this. I wonder how disruptive that would be.

@stevengj
Copy link
Member

stevengj commented May 30, 2018

@JeffBezanson, the difficulty is that this may cause some code to fail if inference fails, rather than just to be slow. e.g. will sum(Number[]) fail if you remove the zero method?

@brenhinkeller brenhinkeller added types and dispatch Types, subtyping and method dispatch maths Mathematical functions labels Nov 21, 2022
@adienes
Copy link
Contributor

adienes commented Nov 11, 2024

duplicate? of #4808

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maths Mathematical functions types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

8 participants