Splatting extra keyword arguments?

I recently tried to splat a collection of extra keyword arguments from one function into another and found it very weird that they are interpreted as non-keyword argument pairs by the second function. For example, take the following

function foo(args... ; kwargs...)
    for i in args
        println("This is an arg: ", i)
    end
    for j in kwargs
        println("This is a kwarg: ", j)
    end
    return args, kwargs
end

a, b = foo(1, 2 , c=3, d=4) #works as expected
foo(a... , b...) #prints all as args, none as kwargs

I get it, but I find it very counter intuitive. Is there a reason that a Pair{Symbol, Any} shouldn’t be interpreted as a keyword argument (assuming the method allows keyword arguments)?

1 Like

foo(a...; b...) forces b... to be interpreted as kwargs – Pair{Symbol, Any} is a perfectly valid input type, so you need some syntactical difference between splattin positional args and kwargs.

3 Likes

I guess my meaning is that every keyword argument is essentially a Pair{Symbol,Any} so I would expect Julia to use the method that has keyword arguments if I pass a Pair{Symbol,Any}, similar to how it prefers a method that has specified types if the argument types match. At the very least I would expect it not to throw an error if I splat into a function that only has keyword arguments

I don’t think I have much to add, but in case you haven’t seen this section before, there’s some good explanation of how Julia’s keyword arguments work in the manual here.

1 Like

That is not how it works, keyword arguments are treated separately from positional ones. This happens as code is parsed, and has nothing to do with dispatch.

2 Likes