SArray, but heterogeneous?

Is it possible to have a Julia type for heterogeneous arrays with compile-time-known sizes? In particular I’m thinking of a heterogeneous matrix, so it would be parameterized by number of rows, number of columns and with a type for each of its elements. The latter part is problematic.

Wait a minute I think I got an idea!

I think this is feasible. You can wrap a Tuple like the other StaticArrays do, except your array would be fully parametrized by the Tuple’s type, which contains the types of each element. It’ll be odd because an AbstractArray should have a singular eltype aka T, but maybe all of your arrays could just use Any. And if you subtype StaticArray too, you’ll have to adhere to more type parameter conventions.

1 Like

I think it’s going to be something like this:

struct HSArray{T <: Tuple, size}
  data::T

  function HSArray(t::T, ::Val{size}) where {T <: Tuple, size}
    (length(t) == prod(size)) || error("sizing error")
    new{T, size}(t)
  end
end

Base.length(::HSArray{<: Tuple, size}) where {size} = prod(size)
Base.size(::HSArray{<: Tuple, size}) where {size} = size

Base.IndexStyle(::HSArray{<: Tuple, size}) where {size} = Base.IndexLinear()

Just need to implement some more interfaces from Interfaces · The Julia Language

Actually, those interfaces would be of limited use for my type because eltype(::HSarray) would need to be Any, as Benny said.

The most useful method for me would be getindex, which seems easy to implement.

Now that I check the Interface docs, the eltype is said to be important, but I’m not familiar with how exactly, except for allocating methods like collect and the default similar. So I don’t know how using Any all the time would pan out. I wondered if the eltype affects the type stability of critical methods like getindex, but it seems like you could just forward it to the wrapped Tuple and it should be inferred , which is technically type-unstable but the compiler does infer the output type given a constant index. setindex! is obviously harder for a wrapped Tuple, but if you intend to implement that, you could look into MArray’s “pointer manipulation”.

1 Like

For my usecase I don’t think I need setindex!, or iteration, and if I don’t need iteration then eltype shouldn’t matter either, I think. So this is easy, unlike what I thought at first.

The default iterate for AbstractArrays is based on scalar getindex, so you’ll get it for free.