StaticArrays.jl icon indicating copy to clipboard operation
StaticArrays.jl copied to clipboard

map SOneTo to SVector

Open tpapp opened this issue 3 years ago • 6 comments

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.

tpapp avatar Jun 01 '22 12:06 tpapp

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.

tpapp avatar Jun 01 '22 12:06 tpapp

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.

jishnub avatar Jun 10 '22 06:06 jishnub

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.

tpapp avatar Jun 10 '22 07:06 tpapp

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.

jishnub avatar Jun 10 '22 10:06 jishnub

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)))

tpapp avatar Nov 06 '23 15:11 tpapp