# Calling functions with named tuples by element name

**URL:** <https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469>\
**Category:** General Usage\
**Tags:** tuple, function\
**Created:** [July 29, 2021, 1:52am UTC](https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469 "2021-07-29T01:52:02Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 29, 2021, 1:52am UTC](https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469/1 "2021-07-29T01:52:02Z")

</div>

Allowing functions to read named tuple elements by name is a wonderful feature of 1.7. Thank you 🙂  
I can now write:

```julia
a,b,c,d = 1:4

f( (;a,b) = (a=0,b=0) ) = a - b

f((;c,d,b,a)) #result -1
f() #result 0

```

It would be great to be able to specify default values within the tuple and optionally omit these in the function call

```julia
f( (;a,b=0) ) = a - b

f((a=1)) #result 1
f((b=2)) #result error - no default value for tuple element 'a' specified.

```

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [July 29, 2021, 1:40pm UTC](https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469/2 "2021-07-29T13:40:56Z")

</div>

I’m having a hard time understanding what this code does.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 29, 2021, 1:48pm UTC](https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469/3 "2021-07-29T13:48:33Z")

</div>

I can see how that feature would be convenient in the particular case you mentioned, but why not instead use normal keyword arguments:

```julia
f(; a, b=0) = a - b

```

which already works exactly as desired:

```julia
julia> f(a=1)
1

julia> f(b=2)
ERROR: UndefKeywordError: keyword argument a not assigned
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

```

Note also that if you happen to have a named tuple, you can still pass it as the keyword arguments to a function:

```julia
julia> args = (a=1, b=2)
(a = 1, b = 2)

julia> f(; args...)
-1

julia> args = (b = 2,)
(b = 2,)

julia> f(; args...)
ERROR: UndefKeywordError: keyword argument a not assigned
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1 

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [July 29, 2021, 7:01pm UTC](https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469/4 "2021-07-29T19:01:04Z")

</div>

> [@rdeits](#):
>
> why not instead use normal keyword arguments

A potential reason is the lack of dispatch by keyword arguments. Dispatch can be used with destructuring in a kinda-convenient way:

```julia
julia> g((;a,b,c)::NamedTuple{(:a,:b,:c)}) = "abc"
g (generic function with 1 method)

julia> g((;a,b)::NamedTuple{(:a,:b)}) = "ab"
g (generic function with 2 methods)

```

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 30, 2021, 12:11pm UTC](https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469/5 "2021-07-30T12:11:23Z")

</div>

`f(; args...)` – That’s a good point. Thank you 🙂

What if `args` also contains an element that isn’t a function variable?  
Can it still be used without causing an error?

I have a function that takes a 10 inputs and returns 5 outputs.  
I want to run it on each row of a CSV which has 30 columns. The necessary field names match with the keyword arguments so I’d like to just send each row to the function without having to filter it down.  
As shown below this gives an error.

```julia
function f(; a=0, b=0 ) 
    x = a + b    
    y = a - b
    (; x, y)
end

D1 = DataFrame( a=1:5 )
D2 = DataFrame( a=1:5, C = 1:5 )

@pipe eachrow(D1) .|> f(;_...) |> DataFrame #works   
@pipe eachrow(D2) .|> f(;_...) |> DataFrame #Error - no C element in function parameters

```

Another option  
transform with ByRow is a fantastic function.  
but you need to map both the inputs and outputs  
If the field names match the function inputs / outputs it would be great you could just tell it to map each row.

```julia
transform(D2, :a => ByRow( a-> f(a=a)) => [:x,:y] ) #works
transform(D2, ALL_COLUMNS => f => COLUMN_NAMES_FROM_OUTPUT ) #Nice to have

```

---

<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:** [July 30, 2021, 12:43pm UTC](https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469/6 "2021-07-30T12:43:25Z")

</div>

> [@Lincoln\_Hannah](#):
>
> The necessary field names match with the keyword arguments so I’d like to just send each row to the function without having to filter it down.

You could just define `f` as:

```julia
function f(; a=0, b=0, _...) 
    x = a + b    
    y = a - b
    (; x, y)
end

```

which should just ignore any additional fields.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [July 30, 2021, 1:58pm UTC](https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469/7 "2021-07-30T13:58:25Z")

</div>

> [@simeonschaub](#):
>
> ` _...)`

could you point out where is the syntax `_...` defined?  
Thank you.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [July 30, 2021, 2:22pm UTC](https://discourse.julialang.org/t/calling-functions-with-named-tuples-by-element-name/65469/8 "2021-07-30T14:22:43Z")

</div>

This is just basic `splat`-ing. See `? ...`. The `_` is just a variable name.
