Confusion over Named Tuples

I have a function which takes as arguments named tuples. But I’m struggling to get it work as I would hope. As a minimal working example consider.

function test(x; a=1.0, b=1.0, c=1.0)
    return x + a + 5*b + 10*c
end 

If I run test(1.0) I get 17.0 as expected. If I run test(1.0, b=10.0, c=10.0) I get 151.0 as expected. But what I would really like is to define a named tuple as a subset of a,b,c and produce output as in the previous examples.

If I create named_tuple = (b=10.0, c=10.0) and run test(1.0, named_tuple...) I get back 17.0 which is just test evaluated at the default values.

In my actual problem I have a function that takes in many named arguments with default values but with the flexibility to specify different values should I wish. I’m creating a subset of named arguments by iterating through the names and values of a data frame and trying to evaluate my function.

Any help would be very much appreciated.

I think you just need to use a ; instead of ,.

julia> f(x; a=1, b=2) = x+a+b
f (generic function with 1 method)

julia> nt = (a=2, b=3)
(a = 2, b = 3)

julia> f(1; nt...)
6

; denotes that you want to splat “named” arguments. It works in many places:

Merge/update named tuples:

julia> nt1 = (a=1,b=2)
(a = 1, b = 2)

julia> nt2 = (a=3,c=4)
(a = 3, c = 4)

julia> (;nt1..., nt2..., d=5)
(a = 3, b = 2, c = 4, d = 5)

Extract only a few components of an object (works for any structs, not just named tuples):

julia> (;a, b) = (a=1,b=2,c=3)
(a = 1, b = 2, c = 3)

julia> a
1

julia> b
2

Something that might help with remembering this: ; is the “proper” way to create a named tuple – parenthesis without a ; is just a syntactic sugar:

julia> (;a=1,b=2) == (a=1,b=2)
true

Edit: you probably also have multiple methods defined for your test function. test(1.0, named_tuple...) should simply raise a MethodError if you have defined only the method you have shared.

11 Likes

Thanks, that’s exactly what I was looking for!