# Slurping on non-final argument

**URL:** <https://discourse.julialang.org/t/slurping-on-non-final-argument/79225>\
**Category:** Internals & Design\
**Tags:** args-function-defini\
**Created:** [April 8, 2022, 1:59pm UTC](https://discourse.julialang.org/t/slurping-on-non-final-argument/79225 "2022-04-08T13:59:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [April 8, 2022, 1:59pm UTC](https://discourse.julialang.org/t/slurping-on-non-final-argument/79225/1 "2022-04-08T13:59:10Z")

</div>

why can i define this function?

```julia
julia> f(y,x...)=+(x...).*y
f (generic function with 1 method)

```

and can’t I define this other one?

```julia
julia> f1(x...,y)=+(x...).*y
ERROR: syntax: invalid "..." on non-final 

```

Couldn’t we gnisrap the arguments in reverse order?

I guess there are many possible side effects to avoid but I am not able to imagine.

---

<div class="post-metadata">

**Author:** ![mbaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbaz/32/17295_2.png) [@mbaz](https://discourse.julialang.org/u/mbaz)\
**Post date:** [April 8, 2022, 2:14pm UTC](https://discourse.julialang.org/t/slurping-on-non-final-argument/79225/2 "2022-04-08T14:14:56Z")

</div>

See this thread: [Optional positional arguments must occur at end - #13 by Jean\_Michel](https://discourse.julialang.org/t/optional-positional-arguments-must-occur-at-end/79051/13)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 8, 2022, 3:05pm UTC](https://discourse.julialang.org/t/slurping-on-non-final-argument/79225/3 "2022-04-08T15:05:44Z")

</div>

This seems to be about slurping, not about optional arguments.

Here’s a PR that addresses this: [https://github.com/JuliaLang/julia/pull/42902](https://github.com/JuliaLang/julia/pull/42902)  
Not sure when/if it will land.

But currently, this is not allowed.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [April 8, 2022, 6:37pm UTC](https://discourse.julialang.org/t/slurping-on-non-final-argument/79225/4 "2022-04-08T18:37:23Z")

</div>

Note that the PR doesn’t address method dispatch as the OP asked for. That would require changes to the type system to actually be able to represent signatures like this.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [September 28, 2026, 8:51am UTC](https://discourse.julialang.org/t/slurping-on-non-final-argument/79225/5 "2026-09-28T08:51:46Z")

</div>

> [@rocco\_sprmnt21](#):
>
> why can i define this function?
> 
> ```julia-repl
> julia> f(y,x...)=+(x...).*y
> 
> ```

The type signature of `f` is representable with `Tuple{Any, Vararg}` in Julia’s type system. In detail: `Any` is for `y::Any`, `Vararg` is for `x::Vararg`.

> [@rocco\_sprmnt21](#):
>
> and can’t I define this other one?
> 
> ```julia-repl
> julia> f1(x...,y)=+(x...).*y
> 
> ```

The type signature of `f1` is not representable in Julia’s type system. `Vararg` can only come in final position.

---

<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:** [September 28, 2026, 11:56pm UTC](https://discourse.julialang.org/t/slurping-on-non-final-argument/79225/6 "2026-09-28T23:56:04Z")

</div>

Even putting aside overhauling the type system to accommodate non-trailing variadic arguments, it just doesn’t make sense. Right now, an input sequence first specifies the non-optional arguments, then fills in for as many optional arguments as possible, then any remaining could be slurped, all while matching type annotations. These input subsequences could be written left-to-right or right-to-left, but we type left-to-right so that’s the order most languages picked. Trying to accommodate both orders at once adds no power to the language but introduces arity ambiguity:

```julia-auto
f(a, b...) = (a, b)
f(a..., b, c) = (a, b, c)

f(1, 2) # parse left-to-right for (1, (2,)) or right-to-left for ((), 1, 2)?

```

Similar problem happens for optional arguments, but the methods more plainly conflict:

```julia-auto
g(a, b=10) = (a, b)
#= currently defines these
g(a, b) = (a,b)
g(a) = g(a, 10)
=#
g(a=10, b, c) = (a, b, c)
#= based on StefanKarpinski's comments in the earlier linked topic
g(a, b, c) = (a, b, c)
g(b, c) = g(10, b, c) # conflicts with g(a, b)
=#

g(1, 2) # parse left-to-right for (1, 2) or right-to-left for (10, 1, 2)?

```

That’s a lot of trouble just for typing inputs somewhat backwards. Assignments don’t have this problem because there aren’t multiple possibilities to consider. I could only find Ruby 2.0 and CoffeeScript as languages with non-trailing variable arguments, and neither natively support multiple method definitions. The one proposal for arity-based multimethods in CoffeeScript I could find immediately [excluded variable arguments](https://github.com/jashkenas/coffeescript/issues/531).
