map SOneTo to SVector
Issue
julia> using StaticArrays
julia> map(i -> (a = i, b = i + 1), axes(SVector(1, 2, 3), 1))
3-element MVector{3, NamedTuple{(:a, :b), Tuple{Int64, Int64}}} with indices SOneTo(3):
(a = 1, b = 2)
(a = 2, b = 3)
(a = 3, b = 4)
is an MVector, while intuitively (and perhaps incorrectly?) I expected an SVector.
Versions
(@v1.8) pkg> st StaticArrays
Status `~/.julia/environments/v1.8/Project.toml`
[90137ffa] StaticArrays v1.4.4 `~/.julia/dev/StaticArrays`
julia> VERSION
v"1.8.0-beta3"
though discussion in #855 suggests this has been around for a while.
Looking at the code, I was wondering if using signatures of the type
mapreduce(f, op, a::Union{SOneTo,StaticArray}, b::Union{SOneTo,StaticArray}...)
would fix this. (The approach of #978 would make this slightly cleaner, instead of hardcoding a concrete type.)
I will wait for comments then make a PR.
This is consistent with Base, though, isn't it?
julia> map(i -> (a = i, b = i + 1), Base.OneTo(3))
3-element Vector{NamedTuple{(:a, :b), Tuple{Int64, Int64}}}:
(a = 1, b = 2)
(a = 2, b = 3)
(a = 3, b = 4)
In this case, given a statically sized axis, we obtain a statically sized mutable vector.
The issue for me is getting SVectors. I am not sure that the interface of Base implies anything about this, map doesn't say anything about the result being mutable, so it is up to this package to decide what to do here.
Generally, I found find it consistent if map(f, ...immutable types defined in this package...) would return an SArray. But that's just a personal preference.
I understand, and I do agree that this could be made allocation-free. However, if you specifically want an SVector, you should probably wrap the result in one instead of relying on the return type of map.
Revisiting this issue: I agree that one should wrap in SVector. But currently SVector(SOneTo(x)) fails, with
ERROR: The size of type `SVector` is not known.
Would it make sense to have have a conversion method, eg along the lines of
SVector(ι::SOneTo{N}) where N = SVector(ntuple(identity, Val(N)))