# Using Vararg for mixed types

**URL:** https://discourse.julialang.org/t/using-vararg-for-mixed-types/108973
**Category:** General Usage
**Tags:** varargs
**Created:** [January 18, 2024, 4:57pm UTC](https://discourse.julialang.org/t/using-vararg-for-mixed-types/108973 "2024-01-18T16:57:37Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Larbino1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/larbino1/32/37831_2.png) [@Larbino1](https://discourse.julialang.org/u/Larbino1)
#### Post date: [January 18, 2024, 4:57pm UTC](https://discourse.julialang.org/t/using-vararg-for-mixed-types/108973/1 "2024-01-18T16:57:37Z")

</div>

Recently I have started getting the error message:

WARNING: Wrapping `Vararg` directly in UnionAll is deprecated (wrap the tuple instead).  
│ You may need to write `f(x::Vararg{T})` rather than `f(x::Vararg{<:T})` or `f(x::Vararg{T}) where T` instead of `f(x::Vararg{T} where T)`.

My problem is I don’t think it is possible for me to dispatch the way I would like with the suggested change.

To give a toy example:  
I want to write a function that accepts all of the following tuples:

```julia
(Int(1), ) 
(Int(1), Int(2), ) 
(Int(1), Int32(2), )
(UInt64(1), UInt32(2), )

```

i.e. any combination of `Integer`s of any length. To accomplish this I use `Vararg{<:Integer}`, which works. Using `Vararg{Integer}` does not work in case 3 or 4 nor does `Vararge{I} where I<:Integer` (which is semantically identical?), only work when all the Integers are the same concrete type, i.e. only matching case 1 and 2.

Why is this being deprecated, and how can I retain the functionality I’m using currently?

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [January 18, 2024, 5:08pm UTC](https://discourse.julialang.org/t/using-vararg-for-mixed-types/108973/2 "2024-01-18T17:08:23Z")

</div>

Dispatch works for me, what are you calling exactly?

```julia
julia> foo(::Vararg{Integer}) = nothing;

julia> foo(Int(1),)

julia> foo(Int(1), Int(2),)

julia> foo(Int(1), Int32(2),)

julia> foo(UInt64(1), UInt32(2),)

```

---

<div class="post-metadata">

### Author: ![Larbino1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/larbino1/32/37831_2.png) [@Larbino1](https://discourse.julialang.org/u/Larbino1)
#### Post date: [January 18, 2024, 5:54pm UTC](https://discourse.julialang.org/t/using-vararg-for-mixed-types/108973/3 "2024-01-18T17:54:27Z")

</div>

Huh… maybe I just did something stupid. Thanks for the sanity check. I’ll give it another go and come back with a concrete example if I still can’t fix it.

---

<div class="post-metadata">

### Author: ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)
#### Post date: [January 18, 2024, 6:50pm UTC](https://discourse.julialang.org/t/using-vararg-for-mixed-types/108973/4 "2024-01-18T18:50:25Z")

</div>

I think the confusion here relates to the covariance/contravariance exception that Julia has made for `Tuple` that makes it different from most other types:

```julia
julia> Vector{Int64} <: Vector{Integer} # most types
false

julia> Tuple{Int64} <: Tuple{Integer} # exception for Tuple
true

julia> Tuple{Int64,UInt8} <: Tuple{Vararg{Integer}} # extends to Vararg
true

```

`Vararg` is intimately related to `Tuple`, although I can’t speak to the precise details of the relationship. But in any case, `Vararg{Integer}` manages to match any number of arguments whose types are `<:Integer` for the same reason that `Tuple` has this behavior.

---

<div class="post-metadata">

### Author: ![Larbino1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/larbino1/32/37831_2.png) [@Larbino1](https://discourse.julialang.org/u/Larbino1)
#### Post date: [January 19, 2024, 12:24pm UTC](https://discourse.julialang.org/t/using-vararg-for-mixed-types/108973/5 "2024-01-19T12:24:56Z")

</div>

Thank you for the explanation. I was aware that tuples are special, as they are how function arguments are represented. Therefore as `f(::Int64, ::Int32)` matches `f(::Integer, ::Integer)` it makes sense that `Vararg` might behave similarly.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [January 19, 2024, 4:17pm UTC](https://discourse.julialang.org/t/using-vararg-for-mixed-types/108973/6 "2024-01-19T16:17:40Z")

</div>

> [@mikmoore](#):
>
> `Vararg` is intimately related to `Tuple`, although I can’t speak to the precise details of the relationship.

> [@Larbino1](#):
>
> I was aware that tuples are special, as they are how function arguments are represented.

Right on the money, `Vararg` is just the parameter for trailing element types of a tuple type, so they are covariant like any other tuple type parameter, not invariant like all other type parameters. In the case of methods, the tuple type is the argument types tuple. For example, `foo(x::Complex, args::Integer...)` has the (abstract) type `Tuple{Complex, Vararg{Integer}}`. The instances correspond to the method’s possible inputs, like `(3+1im, 1, Int32(2))::Tuple{Complex{Int}, Int, Int32}`.

To be more accurate, we’d include the type of the callable too, since that is also dispatched on and is how callable instances work.
