# Varargs and type aliasing

**URL:** https://discourse.julialang.org/t/varargs-and-type-aliasing/77089
**Category:** General Usage
**Created:** [February 25, 2022, 6:29pm UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089 "2022-02-25T18:29:28Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![nchisholm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nchisholm/32/37414_2.png) [@nchisholm](https://discourse.julialang.org/u/nchisholm)
#### Post date: [February 25, 2022, 6:29pm UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/1 "2022-02-25T18:29:29Z")

</div>

I tried to create a type alias of `Vararg` (with a specific number of arguments) as follows.

```julia
const FormArgs{K,D} = Vararg{StaticVector{D}, K}

```

However, if I try `FormArgs{3,2}` it does not produce `Vararg{StaticVector{2},3}` and an error is thrown. I think that is because `Vararg` is not really a `DataType`. Thus, its behavior differs from the similar

```julia
const FormTuple{K,D} = NTuple{K, StaticVector{D}}

```

which works as expected.

However, if you try to use

```julia
f(args::FormTuple{K,D}) where {K,D} = ... # function definition using args[1] ... args[K]

```

you are forced to pass arguments to `f` wrapped in a tuple. In practice, I think you can work around the issue with a helper method

```julia
f(args...) = f(args)

```

but I am wondering if there is a less hacky approach.

* * *

**Edit:** Using `f(args...) = f(args)` as above will result in infinite recursion of `f` into itself if the wrong number of arguments is passed. Better not do that.

In practice, I am using this in a callable type that is parameterized by a known number of arguments, so the pattern is OK:

```julia
(::MyCallable{K})(x::FormTuple{K,D}}) where {K,D} = ...
(instance::MyCallable{K})(x::Vararg{Any,K}) where {K} = instance(x) # defer to method above

```

A `MethodError` is thrown if the wrong number of arguments are used.

---

<div class="post-metadata">

### Author: ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)
#### Post date: [February 26, 2022, 11:33am UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/2 "2022-02-26T11:33:19Z")

</div>

Is

```julia
using StaticArrays
@show StaticVector{3,Int} SVector{3,Int}(1,2,3)
const FormArgs{K,D} = Tuple{Vararg{StaticVector{D},K}}
@show FormArgs{3,2} FormArgs{3,2}((SVector{2}(1,2), SVector{2}(3,4), SVector{2}(5,6)))

```

yielding

```julia
StaticVector{3, Int} = StaticVector{3, Int64}
SVector{3, Int}(1, 2, 3) = [1, 2, 3]
FormArgs{3, 2} = Tuple{StaticVector{2}, StaticVector{2}, StaticVector{2}}
FormArgs{3, 2}((SVector{2}(1, 2), SVector{2}(1, 2), SVector{2}(1, 2))) = ([1, 2], [1, 2], [1, 2])

```

what you are after? AFAIU `Vararg` should (always?) be used in conjunction with `Tuple`?

---

<div class="post-metadata">

### Author: ![nchisholm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nchisholm/32/37414_2.png) [@nchisholm](https://discourse.julialang.org/u/nchisholm)
#### Post date: [February 26, 2022, 7:49pm UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/3 "2022-02-26T19:49:32Z")

</div>

> [@goerch](#):
>
> what you are after? AFAIU `Vararg` should (always?) be used in conjunction with `Tuple`

Thanks for the response. Let me clarify a little.

I was functionally trying to construct a “method signature” alias as a convenient shorthand

```julia
const FormArgs{K,D} = Vararg{StaticVector{D}, K}
f(vs::FormArgs{K,D}) where {K,D} = ...
g(vs::FormArgs{K,D}) where {K,D} = ...
# bunch of other functions with similar methods

```

which I expected to be equivalent to writing

```julia
f(vs::Vararg{StaticVector{D}, K}) where {K,D} = ...

```

But using `Vararg` without `Tuple` like that doesn’t work as you pointed out.

What does work is

```julia
const FormArgs{K,D} = Tuple{Vararg{StaticVector{D}, K}}
f(vs::FormArgs{K,D}) where {K,D} = ...

```

but that requires you to pass arguments like `f((v1, v2, v3))` rather than `f(v1, v2, v3)`, and I want the latter.

I also erroneously tried

```julia
const FormArgs{K,D} = Tuple{Vararg{StaticVector{D}, K}}
f(::FormArgs{K,D}...) where {K,D} = ...

```

but that method expects zero or more `FormArgs{K,D} <: Tuple`s as arguments rather than exactly `K` of `StaticVector{D}`'s.

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [February 27, 2022, 8:12am UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/4 "2022-02-27T08:12:25Z")

</div>

> [@nchisholm](#):
>
> ```julia
> const FormArgs{K,D} = Vararg{StaticVector{D}, K}
> 
> ```

Not sure where the problem is. The following works for me:

```julia
julia> const FormArgs{K,D} = Vararg{StaticVector{D}, K};

julia> blah(x::FormArgs{D,K}) where {D, K} = (D, K);

julia> s = @SVector [1];

julia> blah(s)
(1, 1)

julia> blah(s,s)
(2, 1)

julia> blah(s,s,s)
(3, 1)

```

---

<div class="post-metadata">

### Author: ![nchisholm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nchisholm/32/37414_2.png) [@nchisholm](https://discourse.julialang.org/u/nchisholm)
#### Post date: [February 27, 2022, 3:03pm UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/5 "2022-02-27T15:03:07Z")

</div>

That is interesting. When I try, I get the following error.

```julia
julia> const FormArgs{K,D} = Vararg{StaticVector{D},K}
Vararg{StaticVector}

julia> blah(x::FormArgs{K,D}) where {K,D} = (K, D)
ERROR: ArgumentError: apply_type: too many arguments (expected 2)

```

Also,

```julia
julia> FormArgs{2}
Vararg{StaticVector, 2}

julia> FormArgs{2,3}
ERROR: ArgumentError: apply_type: too many arguments (expected 2)

julia> const FormTuple{K,D} = Tuple{Vararg{StaticVector{D},K}}
Tuple{Vararg{StaticVector{D}, K}} where {K, D}

julia> FormTuple{2,3} # works as expected
Tuple{StaticVector{3}, StaticVector{3}}

```

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [February 27, 2022, 10:56pm UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/6 "2022-02-27T22:56:57Z")

</div>

What julia version are you using? I was on 1.6 above.

* * *

Edit:  
Yes, this fails in 1.7. Now I see what you’re seeing:

```julia
julia> const FormArgs{T, K} = Vararg{T, K} # Note it has nothing to do with StaticArrays
Vararg{Any}

julia> FormArgs{Int, 2}
ERROR: ArgumentError: apply_type: too many arguments (expected 2)
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

```

---

<div class="post-metadata">

### Author: ![nchisholm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nchisholm/32/37414_2.png) [@nchisholm](https://discourse.julialang.org/u/nchisholm)
#### Post date: [February 27, 2022, 11:07pm UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/7 "2022-02-27T23:07:59Z")

</div>

Oh interesting. As you might have guessed, I am using Julia 1.7.

I do not see anything on `Vararg` in the release notes.  
[https://docs.julialang.org/en/v1/NEWS/](https://docs.julialang.org/en/v1/NEWS/)

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [February 27, 2022, 11:41pm UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/8 "2022-02-27T23:41:12Z")

</div>

Strangely, this seems to only apply to `Vararg`.

```julia
julia> Vararg{T, N} where {T, N}
Vararg{Any}

julia> Array{T, N} where {T, N}
Array

julia> NTuple{N, T} where {N, T}
Tuple{Vararg{T, N}} where {N, T} # this is the same as in older versions; no problem here.

```

Julia 1.6 and below:

```julia
julia> Vararg{T, N} where {T, N}
Vararg

```

Whatever caused this change isn’t in the 1.7 release notes as far as I can tell. It’s worth opening a a github issue about it.

To get around it, you can still use the NTuple version. You just need to create a method for non-NTuple Tuples to avoid the infinite recursion:

```julia
julia> const FormArgs{D, K} = NTuple{K, Vector{D}};

julia> f(x::FormArgs{D, K}) where {D, K} = (D, K);

julia> f(x...) = f(x);

julia> f(x::Tuple) = error("non-homogenous tuple");

julia> f([1])
(Int64, 1)

julia> f([1], [1])
(Int64, 2)

julia> f([1], [1.0])
ERROR: non-homogenous tuple
# <...>

```

This will work with your case just as well. The issue is with how aliasing Vararg is working, not with the specific types that are in it.

---

<div class="post-metadata">

### Author: ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)
#### Post date: [February 28, 2022, 8:29am UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/9 "2022-02-28T08:29:51Z")

</div>

> [@tomerarnon](#):
>
> What julia version are you using? I was on 1.6 above.
> 
> Edit:  
> Yes, this fails in 1.7. Now I see what you’re seeing:
> 
> ```julia
> julia> const FormArgs{T, K} = Vararg{T, K} # Note it has nothing to do with StaticArrays
> Vararg{Any}
> 
> julia> FormArgs{Int, 2}
> ERROR: ArgumentError: apply_type: too many arguments (expected 2)
> Stacktrace:
> [1] top-level scope
> @ REPL[3]:1
> 
> ```

Clearly a regression then. You might file an issue?

Edit: [issue](https://github.com/JuliaLang/julia/issues/44391) filed.

---

<div class="post-metadata">

### Author: ![nchisholm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nchisholm/32/37414_2.png) [@nchisholm](https://discourse.julialang.org/u/nchisholm)
#### Post date: [March 2, 2022, 3:31pm UTC](https://discourse.julialang.org/t/varargs-and-type-aliasing/77089/10 "2022-03-02T15:31:06Z")

</div>

> [@goerch](#):
>
> Edit: [issue](https://github.com/JuliaLang/julia/issues/44391) filed.

Thanks! I was about to do the same and then saw that you beat me to it.
