Splat a named tuple before vs after ; in a function call

I did not find this behavior precisely documented elsewhere:

f(args...) = sum(args)
f(;kwargs...) = typeof(kwargs)
f(args...;kwargs...) = args[1] + kwargs[1]
x = (a=1, b=2, c=3)
f(x...)  # = 6
f(;x...)  # = Base.Iterators.Pairs{Symbol,Int64, etc...
f(x...,x...)  # = 12
f(;x...,x...) # = Base.Iterators.Pairs{Symbol,Int64, etc...
f(x...;x...)  # = 2

Ex post, I see that there is a sentence in the Keyword Arguments section of the manual that partly addresses this:

An explicit semicolon is required only for passing varargs or computed keywords as described below.

But it was not obvious to me that f(x...) would ignore the names and simply call the first method rather than throwing an error.

My suggestion is to include examples in the documentation. And my question is whether I am missing any other surprising or interesting behaviors of the splat operator in function calls.

EDIT: A better way to pose my questions is this. What is the rule that explains the “surprising” behavior? Another example of a “surprise” is

f(x...; (a=[])...) # = 6
1 Like

As for the lat example, you need a comma like this (a = [],) for a one argument named tuple, so you aren’t actually passing a named tuple here.

One thing to note is that keyword arguments don’t participate in dispatch, so you are overwriting methods when you define new functions with keyword arguments, rather than creating new ones.

julia> function foo(x)
       println("First method")
       end
foo (generic function with 1 method)

julia> foo(5)
First method

julia> function foo(x; y = 1)
       println("Second method")
       end
foo (generic function with 1 method)

julia> foo(5)
Second method
2 Likes