# Static arrays and type stability under map

**URL:** <https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538>\
**Category:** Performance\
**Tags:** question\
**Created:** [July 20, 2018, 2:03pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538 "2018-07-20T14:03:40Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![vlc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlc/32/4705_2.png) [@vlc](https://discourse.julialang.org/u/vlc)\
**Post date:** [July 20, 2018, 2:03pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538/1 "2018-07-20T14:03:40Z")

</div>

Hello,

I’ve been surprised by the return type of the mapping of a type stable function on a couple of static arrays.

Here is a minimal example, first with regular arrays

```julia
julia> n = 4;

julia> bool = rand(Bool, n);

julia> pair = [rand(1:n, 2) for i in 1:n];

julia> map(pair) do ci 
           (&)(bool[ci]...)
       end;

julia> typeof(ans)
Array{Bool,1}

```

Let’s now use static arrays and look at the type of the result:

```julia
julia> using StaticArrays

julia> sbool = SVector(bool...);

julia> spair = SVector(pair...);

julia> map(spair) do ci 
           (&)(sbool[ci]...)
       end;

julia> typeof(ans)
StaticArrays.SArray{Tuple{4},Any,1,4}

```

I was surprised to see the element type on return to be `Any` instead of `Bool` in this case.

Is this expected? Or am I missing something? I’ve been scratching my head on this one and would be grateful for any feedback!

V.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [July 20, 2018, 4:17pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538/2 "2018-07-20T16:17:08Z")

</div>

What should the code actually do?

---

<div class="post-metadata">

**Author:** ![vlc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlc/32/4705_2.png) [@vlc](https://discourse.julialang.org/u/vlc)\
**Post date:** [July 20, 2018, 5:24pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538/3 "2018-07-20T17:24:20Z")

</div>

Thanks for your reply.

Well I would like the code (with static arrays) to return a `StaticArrays.SArray{Tuple{4},Bool,1,4}` (rather than `StaticArrays.SArray{Tuple{4},Any,1,4}`).

The following (adding `::Bool`) works but I wonder why it’s necessary with static arrays, and not with regular arrays…

```julia
julia> map(spair) do ci
           (&)(sbool[ci]...)::Bool
       end;

julia> typeof(ans)
StaticArrays.SArray{Tuple{4},Bool,1,4}

```

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [July 20, 2018, 5:31pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538/4 "2018-07-20T17:31:34Z")

</div>

My question was what does the `(&)(...)` stuff do, since it is not very comprehensible (to me). Can you give example inputs and outputs? It feels like there should be a better way to do this.

---

<div class="post-metadata">

**Author:** ![vlc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlc/32/4705_2.png) [@vlc](https://discourse.julialang.org/u/vlc)\
**Post date:** [July 20, 2018, 6:06pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538/5 "2018-07-20T18:06:46Z")

</div>

Ok sorry my mistake, here is what I’m trying to do… I have a first array that contains booleans (`bool`), and a second with pairs of indices (`pairs`) pointing to the elements of `bool`.

For each pair, the code should test whether both elements are `true`. Here is a slight rewrite that hopefully will make it more understandable.

```julia
julia> using StaticArrays

julia> n = 10;

julia> m = 5;

julia> sbool = SVector(rand(Bool, n)...);

julia> spair = SVector([rand(1:n, 2) for i in 1:m]...);

julia> map(spair) do ci
           sbool[ci[1]] & sbool[ci[2]]
       end;

julia> typeof(ans)
StaticArrays.SArray{Tuple{5},Any,1,5}

```

This needs to be done very fast, which is why I’m insisting on stick to immutable static arrays. Thanks for your help!

---

<div class="post-metadata">

**Author:** ![traktofon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/traktofon/32/591_2.png) [@traktofon](https://discourse.julialang.org/u/traktofon)\
**Post date:** [July 20, 2018, 6:09pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538/6 "2018-07-20T18:09:24Z")

</div>

`(&)(sbool[ci]...)` can be more idiomatically written as `all(sbool[ci])` but that also results in type instability for `SArray`s.

---

<div class="post-metadata">

**Author:** ![vlc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlc/32/4705_2.png) [@vlc](https://discourse.julialang.org/u/vlc)\
**Post date:** [July 20, 2018, 7:37pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538/7 "2018-07-20T19:37:59Z")

</div>

Looking into [StaticArrays.jl](https://github.com/JuliaArrays/StaticArrays.jl), it seems that the same trick (`::Bool` annotation) is used in the package:

[https://github.com/JuliaArrays/StaticArrays.jl/blob/master/src/mapreduce.jl#L214](https://github.com/JuliaArrays/StaticArrays.jl/blob/master/src/mapreduce.jl#L214)

If anyone reading this topic has an idea of how the annotation could be alleviated I would be curious to learn more…

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [July 20, 2018, 8:24pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538/8 "2018-07-20T20:24:42Z")

</div>

```julia
julia> map(spair) do ci 
           (&)(sbool[ci]...)
       end
4-element SArray{Tuple{4},Any,1,4}:
  true
 false
 false
 false

```

To help see what’s going on, I wanted to use `@code_warntype`, which means wrapping it in a function. Suddenly, it’s type stable:

```julia
julia> foo(spair, sbool) = map(spair) do ci 
           (&)(sbool[ci]...)
       end
foo (generic function with 1 method)

julia> @code_warntype foo(spair, sbool)
Body::SArray{Tuple{4},Bool,1,4}
1 1 ─ %1 = new(getfield(Main, Symbol("##37#38")){SArray{Tuple{4},Bool,1,4}}, %%sbool)::getfield(Main, Symbol("##37#38")){SArray{Tuple{4},Bool,1,4}} │     
  │ %2 = :(StaticArrays.Tuple)::Type{Tuple} │╻╷╷╷ map
  │ Core.apply_type(%2, 4) ││┃│││ _map
  │ %4 = Base.getfield(%%spair, :data)::NTuple{4,Array{Int64,1}} │││╻ macro expansion
  │ %5 = Base.getfield(%4, 1, false)::Array{Int64,1} ││││╻ getindex
  │ %6 = invoke %1(%5::Array{Int64,1})::Bool ││││  
  │ %7 = Base.getfield(%%spair, :data)::NTuple{4,Array{Int64,1}} │││││╻ getproperty
  │ %8 = Base.getfield(%7, 2, false)::Array{Int64,1} │││││╻ getindex
  │ %9 = invoke %1(%8::Array{Int64,1})::Bool ││││  
  │ %10 = Base.getfield(%%spair, :data)::NTuple{4,Array{Int64,1}} │││││╻ getproperty
  │ %11 = Base.getfield(%10, 3, false)::Array{Int64,1} │││││╻ getindex
  │ %12 = invoke %1(%11::Array{Int64,1})::Bool ││││  
  │ %13 = Base.getfield(%%spair, :data)::NTuple{4,Array{Int64,1}} │││││╻ getproperty
  │ %14 = Base.getfield(%13, 4, false)::Array{Int64,1} │││││╻ getindex
  │ %15 = invoke %1(%14::Array{Int64,1})::Bool ││││  
  │ %16 = StaticArrays.tuple(%6, %9, %12, %15)::NTuple{4,Bool} ││││  
  │ %17 = new(SArray{Tuple{4},Bool,1,4}, %16)::SArray{Tuple{4},Bool,1,4} ││││╻ Type
  └── goto 3 ││││  
  2 ─ unreachable ││││  
  3 ─ goto 4 ││    
  4 ─ return %17 │     

julia> foo(spair, sbool)
4-element SArray{Tuple{4},Bool,1,4}:
  true
 false
 false
 false

```

---

<div class="post-metadata">

**Author:** ![vlc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vlc/32/4705_2.png) [@vlc](https://discourse.julialang.org/u/vlc)\
**Post date:** [July 20, 2018, 8:55pm UTC](https://discourse.julialang.org/t/static-arrays-and-type-stability-under-map/12538/9 "2018-07-20T20:55:38Z")

</div>

That did the trick thanks a lot!
