Slurping on non-final argument

why can i define this function?

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

and can’t I define this other one?

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.

See this thread: Optional positional arguments must occur at end - #13 by Jean_Michel

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

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

But currently, this is not allowed.

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.

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.

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

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:

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:

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.