Skip to content

RealInfinity is abstract, but the package assumes it has exactly two subtypes #78

Description

@PatrickHaecker

RealInfinity is declared abstract and exported, which invites downstream subtypes:

abstract type RealInfinity <: Real end
struct PositiveInfinity <: RealInfinity end
struct NegativeInfinity <: RealInfinity end

However signbit is defined only on the two concrete types, with no ::RealInfinity fallback, and sign, angle and every T(x::RealInfinity) conversion are built on it:

signbit(::PositiveInfinity) = false         # src/Infinities.jl:52-53
signbit(::NegativeInfinity) = true
sign(y::RealInfinity) = 1-2signbit(y)       # :71
angle(x::RealInfinity) = π*signbit(x)       # :72
_convert(::Type{T}, x::RealInfinity) where {T<:Real} = sign(x)*convert(T, Inf)   # :64

So a third subtype does not fail cleanly:

julia> struct ThirdInfinity <: Infinities.RealInfinity end

julia> signbit(ThirdInfinity())
ERROR: StackOverflowError:

julia> Float64(ThirdInfinity())
ERROR: StackOverflowError:

It falls through to Base.signbit(x::Real) = x < 0 (number.jl:137) and the comparison then recurses.

Two ways to make the assumption explicit:

  1. Non-breaking — add a signbit(::RealInfinity) fallback that throws a clear error, so an unsupported subtype produces a message instead of a stack overflow.

  2. Breaking — put the closure in the type system:

    struct PositiveInfinity <: Real end
    struct NegativeInfinity <: Real end
    const RealInfinity = Union{PositiveInfinity, NegativeInfinity}

The second option is what was probably intended, at least if the intent is that the extended real line has exactly two points at infinity — with directional infinities living in ComplexInfinity{T} — then option 2 states that in the type system rather than in convention.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions