SizedVector and Float32

I encountered an issue with SizedVector in StaticArrays.jl.

The following works:

i::Int64 = 3
a = SizedVector{i}([1., 2., 3.])

But if i is an Int32, I get an error:

j::Int32 = 3
a = SizedVector{j}([1., 2., 3.])

I get the error:

ERROR: TypeError: in typeassert, expected Tuple{Vararg{Union{StaticArraysCore.Dynamic, Int64}}}, got a value of type Tuple{Int32}
Stacktrace:
 [1] Size
   @ ~/.julia/packages/StaticArraysCore/U2Z1K/src/StaticArraysCore.jl:464 [inlined]
 [2] Size(s::Type{Tuple{3}})
   @ StaticArraysCore ~/.julia/packages/StaticArraysCore/U2Z1K/src/StaticArraysCore.jl:470
 [3] Size(#unused#::Type{SizedVector{3, T} where T})
   @ StaticArraysCore ~/.julia/packages/StaticArraysCore/U2Z1K/src/StaticArraysCore.jl:492
 [4] size(#unused#::Type{SizedVector{3, T} where T})
   @ StaticArrays ~/.julia/packages/StaticArrays/VLqRb/src/abstractarray.jl:4
 [5] length_match_size(#unused#::Type{SizedVector{3, T} where T}, x::Vector{Float64})
   @ StaticArrays ~/.julia/packages/StaticArrays/VLqRb/src/convert.jl:122
 [6] adapt_size(#unused#::Type{SizedVector{3, T} where T}, x::Vector{Float64})
   @ StaticArrays ~/.julia/packages/StaticArrays/VLqRb/src/convert.jl:94
 [7] construct_type(#unused#::Type{SizedVector{3, T} where T}, x::Vector{Float64})
   @ StaticArrays ~/.julia/packages/StaticArrays/VLqRb/src/convert.jl:87
 [8] (SizedVector{3, T} where T)(a::Vector{Float64})
   @ StaticArrays ~/.julia/packages/StaticArrays/VLqRb/src/SizedArray.jl:15
 [9] top-level scope
   @ REPL[36]:1

Question: why can’t I use Int32 to specify the size of the SizedVector? This restriction is either a missed edge case or it is intentional. If it is not a missed edge case, I would like to know the rationale for this decision. Thanks.

1 Like

Type parameters are only used within the compiler, so there is no intrinsic speed or memory cost to a Int64 parameter over an Int32.

Further, canonicalizing the length parameter to a uniform type actually seems very important here. Unsurprisingly,

julia> SizedVector{Int64(3),Float64,Vector{Float64}} === SizedVector{Int32(3),Float64,Vector{Float64}}
false

So, even if non-Int parameters were accepted and you could create the object, it might struggle to interoperate with objects that used a differently-typed type parameter. It would also miss methods for things like LinearAlgebra.cross, which is defined only for objects with Size{(2::Int,)} and Size{(3::Int,)}.

I think that these codebases just get much much harder to write and maintain if they allow non-canonical representations like this. If it mattered, people could eventually support this, but again these values mostly exist within the compiler so there’s little value to adding this support.

StaticArrays.jl is far from alone in this lack of support:

julia> NTuple{Int32(3),Int}
ERROR: TypeError: in Vararg, in count, expected Int64, got a value of type Int32

Thank you for this explanation. Makes complete sense.