# Inferable unpacking of Tuple type to tuple of types

**URL:** <https://discourse.julialang.org/t/inferable-unpacking-of-tuple-type-to-tuple-of-types/66329>\
**Category:** General Usage\
**Created:** [August 13, 2021, 9:24am UTC](https://discourse.julialang.org/t/inferable-unpacking-of-tuple-type-to-tuple-of-types/66329 "2021-08-13T09:24:45Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![juthohaegeman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juthohaegeman/32/8620_2.png) [@juthohaegeman](https://discourse.julialang.org/u/juthohaegeman)\
**Post date:** [August 13, 2021, 9:24am UTC](https://discourse.julialang.org/t/inferable-unpacking-of-tuple-type-to-tuple-of-types/66329/1 "2021-08-13T09:24:45Z")

</div>

In one of my packages, I used the following paradigm to unpack a `Tuple{T1,T2,...}` into a tuple of the types

```julia
unpack(::Type{Tuple{}}) = ()
unpack(::Type{T}) where {T<:Tuple} = (Base.tuple_type_head(T), unpack(Base.tupe_type_tail(T))...)

```

which I could then use to compute some property thereof, and the end result was completely inferred up to Julia 1.6.x. So as an example (not the actual code that I want to do)

```julia
function test(x::Tuple)
     types = unpack(typeof(x))
     return promote_type(types)
end

@code_warntype test((1,2.,3//4))

```

This worked fine with all of the recent Julia versions. With Julia 1.7.DEV, the result is no longer inferred. Adding `@inline` in the `unpack` definition does not seem to help. The only thing that helps is adding `Base.@pure` in front of the `unpack` definition. However, given all the warning regarding the use of `@pure`, I actually removed all my use cases of it and was happy to see that things were working without it.

Is this a valid use case for `@pure`? Or a bug that it is no longer inferred? Or is there a better paradigm for doing something like this altogether?

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [August 13, 2021, 9:37am UTC](https://discourse.julialang.org/t/inferable-unpacking-of-tuple-type-to-tuple-of-types/66329/2 "2021-08-13T09:37:42Z")

</div>

You can perhaps use a generated function?  
Edit: Apparently the function below constant folds even without the `@generated`.

```julia
julia> @generated unpack(::Type{T}) where {T <: Tuple} = Tuple(T.parameters)
unpack (generic function with 1 method)

julia> @code_native unpack(typeof((1, 1.0, 3//4)))
	.section	__TEXT,__ text,regular,pure_instructions
; ┌ @ REPL[9]:1 within `unpack`
	movq	%rdi, %rax
	movabsq	$4542686688, %rcx ## imm = 0x10EC3E5E0
	movq	(%rcx), %rcx
	movq	%rcx, 16(%rdi)
	movabsq	$4542686672, %rcx ## imm = 0x10EC3E5D0
	vmovups	(%rcx), %xmm0
	vmovups	%xmm0, (%rdi)
	retq
	nopw	(%rax,%rax)
; └

```

---

<div class="post-metadata">

**Author:** ![juthohaegeman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juthohaegeman/32/8620_2.png) [@juthohaegeman](https://discourse.julialang.org/u/juthohaegeman)\
**Post date:** [August 13, 2021, 9:45am UTC](https://discourse.julialang.org/t/inferable-unpacking-of-tuple-type-to-tuple-of-types/66329/3 "2021-08-13T09:45:42Z")

</div>

Yes, I guess `@generated` would be another solution. I used to be a big fan of `@generated` functions, but because of the warnings about their limitations I started to shy away from them in favour of recursive definitions and tuple manipulations like in my `unpack` implementation. So indeed, I would like to know what the “recommended” approach is.
