# Type-instability indexing tuple

**URL:** https://discourse.julialang.org/t/type-instability-indexing-tuple/36528
**Category:** General Usage
**Created:** [March 25, 2020, 11:08pm UTC](https://discourse.julialang.org/t/type-instability-indexing-tuple/36528 "2020-03-25T23:08:04Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![jonas-kr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonas-kr/32/1810_2.png) [@jonas-kr](https://discourse.julialang.org/u/jonas-kr)
#### Post date: [March 25, 2020, 11:08pm UTC](https://discourse.julialang.org/t/type-instability-indexing-tuple/36528/1 "2020-03-25T23:08:04Z")

</div>

Is it possible to modify the following piece of code such that it becomes type-stable?

```julia
julia> function f(x)
       for k in eachindex(x)
       display(x[k])
       end
       end;

julia> a = tuple(1:2,1.0:2.0)
(1:2, 1.0:1.0:2.0)

julia> f(a)
1:2
1.0:1.0:2.0

julia> @code_warntype f(a)
Variables
  #self#::Core.Compiler.Const(f, false)
  x::Tuple{UnitRange{Int64},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}
  @_3::Union{Nothing, Tuple{Int64,Int64}}
  k::Int64

Body::Nothing
1 ─ %1 = Main.eachindex(x)::Core.Compiler.Const(Base.OneTo(2), false)
│ (@_3 = Base.iterate(%1))
│ %3 = (@_3::Core.Compiler.Const((1, 1), false) === nothing)::Core.Compiler.Const(false, false)
│ %4 = Base.not_int(%3)::Core.Compiler.Const(true, false)
└── goto #4 if not %4
2 ┄ %6 = @_3::Tuple{Int64,Int64}::Tuple{Int64,Int64}
│ (k = Core.getfield(%6, 1))
│ %8 = Core.getfield(%6, 2)::Int64
│ %9 = Base.getindex(x, k)::Union{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, U
nitRange{Int64}}
│ Main.display(%9)
│ (@_3 = Base.iterate(%1, %8))
│ %12 = (@_3 === nothing)::Bool
│ %13 = Base.not_int(%12)::Bool
└── goto #4 if not %13
3 ─ goto #2
4 ┄ return

```

Thank you very much in advance!

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [March 25, 2020, 11:14pm UTC](https://discourse.julialang.org/t/type-instability-indexing-tuple/36528/2 "2020-03-25T23:14:55Z")

</div>

This code can not be made to be type stable. That said, it is unlikely to matter here.

---

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [March 25, 2020, 11:24pm UTC](https://discourse.julialang.org/t/type-instability-indexing-tuple/36528/3 "2020-03-25T23:24:40Z")

</div>

`display` is itself not stable and you can’t really fix that (nor is it a function that you might care about trying to), but for small tuples, you _can_ get rid of the type instability introduced by the loop by using `map` instead. E.g. compare the output of:

```julia
function f(x)
   for k in eachindex(x)
      identity(x[k])
   end
end
@code_warntype f(a)

```

which will show the `getindex` is not inferred (since the value of `k` is unknown at compile time and the return type will depend on it):

```julia
│ %9 = Base.getindex(x, k)::Union{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, UnitRange{Int64}}

```

vs. the output of:

```julia
function f(x)
   map(identity, x)
end
@code_warntype f(a)

```

which is fully inferred. Note though even this will not be inferred if the tuple has more than 16 elements.

---

<div class="post-metadata">

### Author: ![jonas-kr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonas-kr/32/1810_2.png) [@jonas-kr](https://discourse.julialang.org/u/jonas-kr)
#### Post date: [March 26, 2020, 11:59am UTC](https://discourse.julialang.org/t/type-instability-indexing-tuple/36528/4 "2020-03-26T11:59:25Z")

</div>

Thank you very much for your quick responses! 🙂 I should have chosen another MWE since I did not care about the `display` part, only about the indexing into the tuple. Unfortunately, it is not possible to use `map` for my purposes as I have to index into a product-iterator on the right-hand side…

However, I have fixed the type instability by promoting the types within the initial tuple, which, in spite of my concerns, did not significantly slow things down.

---

<div class="post-metadata">

### Author: ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)
#### Post date: [March 26, 2020, 1:25pm UTC](https://discourse.julialang.org/t/type-instability-indexing-tuple/36528/5 "2020-03-26T13:25:05Z")

</div>

You can often use `ntuple(i -> f(tup[i]), length(tup))` in place of a `for` loop, which like `map` behaves well for tuples.

---

<div class="post-metadata">

### Author: ![jonas-kr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jonas-kr/32/1810_2.png) [@jonas-kr](https://discourse.julialang.org/u/jonas-kr)
#### Post date: [March 26, 2020, 3:14pm UTC](https://discourse.julialang.org/t/type-instability-indexing-tuple/36528/6 "2020-03-26T15:14:07Z")

</div>

My first approach to my problem had exactly this form and accordingly comprises only two lines of code. Unfortunately, it seems like there is no way to speed things up significantly… Filling the tuple manually with a `for`-loop enables the use of multiple threads, which helps only in case of large inputs.

Thanks a lot for your reply! 🙂
