Confused by "Type"

I’m confused by this snippet from https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array:

julia> struct SquaresVector <: AbstractArray{Int, 1}
           count::Int
       end

julia> Base.IndexStyle(::Type{<:SquaresVector}) = IndexLinear()

Why do we need ::Type{<:SquaresVector}) in the definition of Base.IndexStyle? I’d have written ::SquaresVector instead, and this simpler definition also seems to work. The code listed above seems to refer to a subtype of SquaresVector. But this is a concrete type, and I thought it was illegal to derive a new type from a concrete type.

2 Likes

I wrote that, and did so intentionally. You’re right that it’s not needed for SquaresVector, but you do still need to use ::Type{SquaresVector}. The vast vast majority of AbstractArray subtypes will have type parameters… and it’s in that case where you’d need the <: clause.

You don’t just want to define this for values of type ::SquaresVector, however, because IndexStyle is a trait for the type itself (and there are some callers that will just ask for IndexStyle(SquaresVector).

5 Likes

Something to also take into account is that by default

IndexStyle(A::AbstractArray) = IndexStyle(typeof(A))

So if you use

Base.IndexStyle(::Type{<:SquaresVector}) = IndexLinear()

you automatically also change Base.IndexStyle(::SquaresVector). But the converse is not true:

julia> struct SquaresVector <: AbstractArray{Int, 1}
           count::Int
       end

julia> Base.IndexStyle(::SquaresVector) = IndexLinear()

julia> s = SquaresVector(4);

julia> IndexStyle(s)
IndexLinear()

julia> IndexStyle(SquaresVector)
IndexCartesian()
2 Likes

Why do you need the <: operator? Seems to work without it:

julia> struct SquaresVector <: AbstractArray{Int, 1}
                  count::Int
              end

julia> Base.IndexStyle(::Type{SquaresVector}) = IndexLinear()

julia> s = SquaresVector(3);

julia> IndexStyle(s)
IndexLinear()

julia> IndexStyle(SquaresVector)
IndexLinear()

That’s what I first thought you were talking about — the <: is only unnecessary if your type doesn’t have parameters. Most AbstractArray subtypes do have parameters, however, and in that case it’s needed because you want to capture all possible parameterizations.

2 Likes