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

isreal does not work in type domain #56684

Closed
lkdvos opened this issue Nov 26, 2024 · 4 comments
Closed

isreal does not work in type domain #56684

lkdvos opened this issue Nov 26, 2024 · 4 comments

Comments

@lkdvos
Copy link

lkdvos commented Nov 26, 2024

There is something that I ran into this week, which somehow was unexpected to me. While real and complex work in the type domain, isreal does not. I can see why this would be the case, but it's also not super intuitive that it does not work.

julia> T = Float64
Float64

julia> real(T)
Float64

julia> complex(T)
ComplexF64 (alias for Complex{Float64})

julia> isreal(T)
ERROR: MethodError: no method matching isreal(::Type{Float64})
The function `isreal` exists, but no method is defined for this combination of argument types.

...
@mikmoore
Copy link
Contributor

help?> isreal
search: isreal isready real isreadonly isreadable isequal iszero break iswritable isperm Real issetequal read istril

  isreal(x) -> Bool

  Test whether x or all its elements are numerically equal to some real number including infinities and NaNs.
  isreal(x) is true if isequal(x, real(x)) is true.

I guess because the docstring does not indicate this as a valid usage.

I think there is extremely little precedent for functions that operate like this. We already have T <: Real for this purpose. I despair at the possibility of needing to maintain a bunch of isX functions that should simply be T <: X. The only reason to have separate functions for this would be if we didn't want them to utilize the type hierarchy (i.e., to be traits instead). But the prospect of a value that is isreal but not <:Real (or the reverse) seems quite difficult to work with.

@lkdvos
Copy link
Author

lkdvos commented Nov 26, 2024

I would argue that isreal(::Type{T}) where {T<:Number} = T <: Real is not a bad default, but it could also be isreal(t) = t == real(t).
I guess you are right on the money, the function sounds very much like a trait, and it occupies the name I would use for that trait.
I am quite okay with T <: Real but that would then make the code only work for explicit subtypes of Real, which is sometimes not possible because of other constraint.
More than anything, I was just slightly confused for half a minute, because I expected it to just work without thinking.
After thinking about it, I do see that it's technically a bit strange, since Float64 is not a real number, it is a type.
But then it is slightly inconsistent that real and complex do work in the type domain.

Again, not a big issue, just wanted to bring it up.

@giordano
Copy link
Contributor

If anything, I'd expect that isreal(T) would be true for all values of the type T, but for example

julia> isreal(complex(1))
true

from which we should infer isreal(ComplexF64) should be true?

@lkdvos
Copy link
Author

lkdvos commented Nov 27, 2024

Ah, I never thought about that, that's a very good counterargument. Thanks for explaining!

@lkdvos lkdvos closed this as completed Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants