I’m trying understand type stability of functions like

```
f(t::Tuple) = tuple(t...)
g(t::Tuple) = tuple((identity(l) for l in t)...)
```

`identity`

here is meant to be a place-holder for any type stable function. Of the two, `f`

is stable, `g`

is not:

```
julia> t = (:a, 1, 0.1);
julia> @code_warntype f(t)
Variables
#self#::Core.Compiler.Const(f, false)
t::Tuple{Symbol,Int64,Float64}
Body::Tuple{Symbol,Int64,Float64}
1 ─ %1 = Core._apply_iterate(Base.iterate, Main.tuple, t)::Tuple{Symbol,Int64,Float64}
└── return %1
julia> @code_warntype g(t)
Variables
#self#::Core.Compiler.Const(g, false)
t::Tuple{Symbol,Int64,Float64}
Body::Tuple{Vararg{Union{Float64, Int64, Symbol},N} where N}
1 ─ %1 = Base.Generator(Main.identity, t)::Base.Generator{Tuple{Symbol,Int64,Float64},typeof(identity)}
│ %2 = Core._apply_iterate(Base.iterate, Main.tuple, %1)::Tuple{Vararg{Union{Float64, Int64, Symbol},N} where N}
└── return %2
```

There are two, possibly related, things I don’t understand here. First, what exactly does `tuple(t...)`

do? I would have expected this to `iterate`

through `t`

, and pass the results onto `tuple`

. But I guess that’s not what’s happening, since `iterate`

doesn’t seem to be type stable:

```
julia> @code_warntype iterate(t)
Variables
#self#::Core.Compiler.Const(iterate, false)
t::Tuple{Symbol,Int64,Float64}
Body::Union{Nothing, Tuple{Union{Float64, Int64, Symbol},Int64}}
1 ─ nothing
│ nothing
│ %3 = (#self#)(t, 1)::Union{Nothing, Tuple{Union{Float64, Int64, Symbol},Int64}}
└── return %3
```

So what exactly does splatting do then, and is this explained somewhere in the manual?

Second, for `g`

, I’ve come to the conclusion that its type instability is probably caused by the compiler not being able to infer the length of a `Base.Generator{NTuple{N,T}}`

from its type. Is there a reason why this is so? Could there be something like a value for `IteratorSize`

called `TypeHasLength()`

that would be a guarantee that `length(::T) = length(T)`

for this type `T`

, i.e. the length is inferable from the type? This seems to me like it would make a lot of sense for `Tuple`

s, and probably also for a lot of user-defined composite types that have a number of fields, and `iterate`

just goes through them. This is actually the original use case that got me thinking about all this: A user-defined, iterable type for which I would like a function like `g`

to be type stable.