How to programmatically determine the type of a Tuple minus its first parameter?

When working with tuples, you can ‘pop’ the first entry via dispatch as follows:

tuplepop(t::Tuple{<:Any, Vararg}) = t[2:end]
tuplepop(t::Tuple{}) = t

But how can I determine the type of the result ahead of time?

This is the best I can come up with, but it’s hideous:

tuplepop_type(::Type{T}) where T<:Tuple{<:Any, Vararg} = Tuple{T.parameters[2:end]...}
tuplepop_type(::Type{Tuple{}}) = Tuple{}

I’d just use tuplepop(t::Tuple) = typeof(Base.tail(t)) That’ll error on empty tuples, but you can easily add the Tuple{} case as a second method.

1 Like

Thank you, easy solution!

Oh wait, actually is there some way of determining the return type with only the argument type? It’d be nice to just work with the types.

julia> Base.tuple_type_tail(Tuple{Int,Int,Float64})
Tuple{Int64,Float64}

It’s not exported, but it’s better than all other non-exported methods for doing the same.

2 Likes

Thanks! There’s an amazing amount of useful things lurking in Base.

Do you know what Julia’s policy is on non-exported functions in Base? I assume if functions are not exported from Base then there’s no guarantee that they won’t disappear across versions.

1 Like

They can indeed disappear without deprecations, but at least the maintainers of Base do not to introduce different semantics and keep the name, so your unit tests should catch the change and you can rewrite.

2 Likes