# Function arguments

**URL:** https://discourse.julialang.org/t/function-arguments/61717
**Category:** General Usage
**Tags:** tuple, function, namedtuple, named-tuple
**Created:** [May 24, 2021, 11:36am UTC](https://discourse.julialang.org/t/function-arguments/61717 "2021-05-24T11:36:31Z")
**Posts on this page:** 20
**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: [May 24, 2021, 11:36am UTC](https://discourse.julialang.org/t/function-arguments/61717/1 "2021-05-24T11:36:31Z")

</div>

Is it possible to pass a named tuple to a function and have the components available as variables without explicitly specifying them as arguments.

```julia
f( X ) = A + B
X = (A=1,B=2)
f( X )

```

output : `3`

Background: I have about 20 variables and a dozen functions. Each function uses a subset of the variables. I don’t want to have to specify each subset at the start of each function. I’d rather just send a single named tuple, but don’t want to have to write X.A, X.B if its possible to just write A, B

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [May 24, 2021, 11:40am UTC](https://discourse.julialang.org/t/function-arguments/61717/2 "2021-05-24T11:40:06Z")

</div>

No, not automatically. You will have to specify the arguments manually or unpack the tuple.

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [May 24, 2021, 11:43am UTC](https://discourse.julialang.org/t/function-arguments/61717/3 "2021-05-24T11:43:23Z")

</div>

Take a look at `@unpack` in `Parameters.jl`. You may also be interested in `ComponentArrays.jl`.

---

<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: [May 24, 2021, 11:43am UTC](https://discourse.julialang.org/t/function-arguments/61717/4 "2021-05-24T11:43:49Z")

</div>

will do thanks

---

<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: [May 24, 2021, 11:57am UTC](https://discourse.julialang.org/t/function-arguments/61717/5 "2021-05-24T11:57:15Z")

</div>

Had a look at these. It seems you still have to list the variable names. e.g. a, b = unpack(X)  
The only way I found to unpack without listing the variable names is something messy like:

```
`@pipe names(X) .|> @eval( $(Symbol(X)) = $(r[X]) )`

```

---

<div class="post-metadata">

### Author: ![mike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike/32/39_2.png) [@mike](https://discourse.julialang.org/u/mike)
#### Post date: [May 24, 2021, 12:47pm UTC](https://discourse.julialang.org/t/function-arguments/61717/6 "2021-05-24T12:47:42Z")

</div>

> [@Lincoln\_Hannah](#):
>
> `@eval( $(Symbol(X)) = $(r[X]) )`

`@eval` will evaluate those names into the global scope rather than into the function as locals, so probably not what you’d want either maybe if you’re wanting to unpack function arguments?

---

<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: [May 24, 2021, 12:52pm UTC](https://discourse.julialang.org/t/function-arguments/61717/7 "2021-05-24T12:52:18Z")

</div>

yes

---

<div class="post-metadata">

### Author: ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)
#### Post date: [May 24, 2021, 1:07pm UTC](https://discourse.julialang.org/t/function-arguments/61717/8 "2021-05-24T13:07:07Z")

</div>

This is I think close to what you want

```julia
julia> f((A,B)) = A + B
f (generic function with 1 method)

julia> f((A=1, B=2))
3

```

---

<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: [May 24, 2021, 1:15pm UTC](https://discourse.julialang.org/t/function-arguments/61717/9 "2021-05-24T13:15:38Z")

</div>

Sorry Tomak. I was hoping to not specify the A and B at all

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [May 24, 2021, 1:24pm UTC](https://discourse.julialang.org/t/function-arguments/61717/10 "2021-05-24T13:24:25Z")

</div>

As I said before - unpacking without specifying which variables you want is not possible, sorry. Variable names don’t exist anymore at the time your named tuple is passed in. You _could_ do it with a generated function, but that’s really going to be more of a hassle than convenience (which is what you’re looking for) since now every function you’d write would have to be generated. There are also a bunch of limitations of generated functions that make them unsuitable for regular development.

---

<div class="post-metadata">

### Author: ![mike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike/32/39_2.png) [@mike](https://discourse.julialang.org/u/mike)
#### Post date: [May 24, 2021, 1:41pm UTC](https://discourse.julialang.org/t/function-arguments/61717/11 "2021-05-24T13:41:41Z")

</div>

Your simplest option if you don’t want to repeat argument names everywhere and keep them in sync is to use `Parameters` like @amrods has suggested:

```julia
julia> using Parameters

julia> @with_kw struct T
           A
           B
       end
T

julia> f(X::T) = (@unpack_T X; A + B)
f (generic function with 1 method)

julia> f(T(A = 1, B = 2))
3

```

I don’t believe you can use `NamedTuple`s for the `@unpack_T` feature.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [May 24, 2021, 2:00pm UTC](https://discourse.julialang.org/t/function-arguments/61717/12 "2021-05-24T14:00:40Z")

</div>

> [@mike](#):
>
> keep them in sync is to use `Parameters`

That has the disadvantage of clobbering function scope with (potentially) unnecessary variables, which may shadow other variables and can lead to very subtle bugs.

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [May 24, 2021, 2:38pm UTC](https://discourse.julialang.org/t/function-arguments/61717/13 "2021-05-24T14:38:23Z")

</div>

Try the `@with` macro from [StaticModules.jl](https://github.com/MasonProtter/StaticModules.jl).

```julia
function f(nt)
    @with nt begin
        a + b
    end
end

x = (a = 1, b = 2)

```

```julia
julia> f(x)
3

```

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [May 24, 2021, 6:03pm UTC](https://discourse.julialang.org/t/function-arguments/61717/14 "2021-05-24T18:03:22Z")

</div>

> [@Sukera](#):
>
> That has the disadvantage of clobbering function scope with (potentially) unnecessary variables, which may shadow other variables and can lead to very subtle bugs.

Which seems to be exactly what OP wants, they do not want to need to declare which variables they will be taking from the struct so necessarily they want to dump all names on some scope.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [May 24, 2021, 9:37pm UTC](https://discourse.julialang.org/t/function-arguments/61717/15 "2021-05-24T21:37:59Z")

</div>

In this simple example, yes, but if OP only wants a subset of all fields (as indicated in the OP), the additional names may clobber other variables that are incidentally named the same, which I don’t think was the intention.

---

<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: [May 24, 2021, 9:43pm UTC](https://discourse.julialang.org/t/function-arguments/61717/16 "2021-05-24T21:43:33Z")

</div>

> [@tomaklutfu](#):
>
> ```julia
> julia> f((A,B)) = A + B
> f (generic function with 1 method)
> 
> julia> f((A=1, B=2))
> 3
> 
> ```

This will destructure by index instead of by name, so `f((B=2, A=1))` will set `A` to 2 and `B` to 1. In 1.7, you will be able to write this as `f((; A, B)) = A + B`, which will destructure by name instead.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [May 25, 2021, 12:07am UTC](https://discourse.julialang.org/t/function-arguments/61717/17 "2021-05-25T00:07:50Z")

</div>

Well, to me it seems to be exactly what they want as they say:

> [@Lincoln\_Hannah](#):
>
> I don’t want to have to specify each subset at the start of each function.

---

<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: [May 25, 2021, 12:32am UTC](https://discourse.julialang.org/t/function-arguments/61717/18 "2021-05-25T00:32:47Z")

</div>

`f((; A, B)) = A + B`

I like this. Can you add defaults ?

```julia
f((; A=1, B=2)) = A+B
X = (A=2)

>julia f( X )
4

```

---

<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: [May 25, 2021, 3:30am UTC](https://discourse.julialang.org/t/function-arguments/61717/19 "2021-05-25T03:30:19Z")

</div>

More generally will 1.7 allow

- Define all arguments with keywords and defaults
- Call with a named tuple such that:  
elements in function def but not in tuple use default values (or error if default not specified)  
elements in tuple but not function def are ignored

---

<div class="post-metadata">

### Author: ![bertlhf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertlhf/32/38078_2.png) [@bertlhf](https://discourse.julialang.org/u/bertlhf)
#### Post date: [December 16, 2024, 4:11pm UTC](https://discourse.julialang.org/t/function-arguments/61717/20 "2024-12-16T16:11:09Z")

</div>

> [@Lincoln\_Hannah](#):
>
> `f((; A=1, B=2)) = A+B`

```julia
Julia> f((; A=1, B=2)) = A+B
ERROR: syntax: invalid argument destructuring syntax "(; A = 1, B = 2,)" around REPL[84]:1

```

What has changed in the past 3 years that I have an error now?

[Next page](https://discourse.julialang.org/t/function-arguments/61717.md?page=2)
