I am trying to battle, overcome regressions when moving to Julia 0.7. Let’s say I have the function

```
function next_collision(
p::AbstractParticle{T}, bt::Tuple)::Tuple{T,Int} where {T}
tmin::T = T(Inf)
ind::Int = 0
for i in eachindex(bt)
tcol::T = collisiontime(p, bt[i])
# Set minimum time:
if tcol < tmin
tmin = tcol
ind = i
end
end#obstacle loop
return tmin, ind
end
```

I want to make it faster because doing `bt[i]`

isn’t very good. That is because the elements of the tuple `bt`

are not the same type. They are all subtypes of the same abstract type, but they are not the same concrete type.

I thought I could use metaprogramming to “unroll” the loop, something similar with the package Unrolled.jl.

But I think I don’t know how to get the length of a tuple by its type?.. This is what I have:

```
@generated function next_collision3(p::AbstractParticle{T}, bt::TUP) where {T, TUP}
L = length(TUP)
quote
i::Int = 0; ind::Int = 0
tmin::T = T(Inf)
for i in 1:L
let x = bt[i]
tcol::T = collisiontime(p, x)
# Set minimum time:
if tcol < tmin
tmin = tcol
ind = i
end
end
end
end
end
```

`bt`

is a Tuple. But `length(TUP)`

doesn’t work. But the actual length of a tuple is know by its type, right?

EDIT: The **answer** of how to do this, by slightly modifying an answer by @mauro3, is:

```
@generated function next_collision(p::AbstractParticle{T}, bt::TUP) where {T, TUP}
L = fieldcount(TUP)
out = quote
i = 0; ind = 0
tmin = T(Inf)
end
for j=1:L
push!(out.args,
quote
let x = bt[$j]
tcol = collisiontime(p, x)
# Set minimum time:
if tcol < tmin
tmin = tcol
ind = $j
end
end
end
)
end
push!(out.args, :(return tmin, ind))
return out
end
```

The result is non allocating and almost perfectly benchmarks equal to the sum of doing the `collisiontime`

individually for each entry in the tuple.