Skip to content

What does T mean in AbstractArray{T}? #9586

@timholy

Description

@timholy

This is inspired by our head-scratching over in JuliaMath/Interpolations.jl#17. I couldn't find an open issue on this, but apologies if this is a dupe. It is surely related to #8974, #8027.

The meaning of eltype is fairly clear for a stored array, but it's less clear for an array type that involves computation. For example, here's something that sure looks like an AbstractArray, for which it seems to make sense to define a getindex that involves computation:

type InterpArray1D{T} <: AbstractArray{T, 1}
    a::Array{T,1}
    shift::Float64
end

function getindex(A::InterpArray1D, i)
    ix = floor(Int, real(i)+A.shift)
    dx = i - ix
    convert(eltype(A), (1-dx)*A.a[ix] + dx*A.a[ix+1])
end

Note that if you omit the convert, you are not guaranteed to return an "element" of type T---the return type would depend not only on the concrete type of A, but also that of i.

There are situations, however, when multiple-dispatch type-dependency might be desirable. For example, if one omitted the call to convert, one could use DualNumbers.jl to also compute the gradient (e.g., A[dual(5,1)] would compute both the value and slope at i=5). Skipping the convert does not automatically make it type-unstable, of course, as long as the return type can be inferred. In that sense, one can make the argument that getindex is just a normal function and our usual preference for duck-typing should apply.

So this raises the question: do we have a clear definition of what AbstractArray{T} really means? This documentation page says it means "the type of the elements contained in A", which would appear to make it OK to skip the convert in getindex. However, I'll wager that we have a lot of code that assumes that A[1] returns an object of type eltype(A).

FYI over in Interpolations we've also thought about not making this kind of thing a subtype of AbstractArray; the biggest loss would seem to be the ability to create a SubArray out of an InterpArray1D, which is definitely something that comes up in practice.

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsThis change adds or pertains to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions