# Calling type-unstable functions within a type-stable function (and usage of Val)

I have a function `f` that is potentially type-unstable. I also have a function `g` that in the end is type-stable, but inside it calls `f`.

Here is an (artificial) example, implemented in different ways:

``````f1(t::Tuple, i::Int) = t[i]
g1(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f1(thetupl, i), Val(n))

f2(t::Tuple, ::Val{i}) where {i} = t[i]
g2(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f2(thetupl, Val(i)), Val(n))

f3(t::Tuple, ::Val{i}) where {i} = t[i]
f3(t::Tuple, i::Int) = t[i]
g3(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f3(thetupl, i), Val(n))
g4(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f3(thetupl, Val(i)), Val(n))

f5(t::Tuple, i::Int) = f2(t::Tuple, Val(i))
g5(thetupl::Tuple, ::Val{n}) where {n} = ntuple(i -> f5(thetupl, i), Val(n))
``````

All the versions of `g` are type-stable (in theory). However `f1`, `f3`, `f5` are potentially type-unstable because their output types can depend on the value of `i`, when the tuple `t` has items of heterogeneous types.

To experiment, I created an heterogeneous tuple:

``````julia> thetupl = ntuple(i -> rand((rand(1:10), rand("da;glaergerf"), "afdsa", rand(Bool), randn())), 20)
("afdsa", false, false, "afdsa", "afdsa", true, 9, false, 4, false, 'l', 'l', 'e', false, 0.21198045684894534, -0.9550998919808197, 'f', false, "afdsa", "afdsa")
``````

Then I inspected the type-stability of the different versions of `g` as inferred by Julia, using `@inferred g1(thetupl, Val(5))`, and so on for the other variations of `g`. Turns out that `g1`, `g3` are seen as type-stable by Julia, while `g2`, `g4`, `g5` are not! I was surprised by this, and would like to understand why.

I actually have some slightly more complicated code with a related issue, so I am trying to understand what is the best way to deal with these “spurious” type instabilities inside type-stable functions.

In case this depends on compiler internals that might change with version, I am using Julia 1.3.1 here.