# Several layers of keyword arguments

**URL:** https://discourse.julialang.org/t/several-layers-of-keyword-arguments/21956
**Category:** General Usage
**Created:** [March 17, 2019, 5:49am UTC](https://discourse.julialang.org/t/several-layers-of-keyword-arguments/21956 "2019-03-17T05:49:51Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)
#### Post date: [March 17, 2019, 5:49am UTC](https://discourse.julialang.org/t/several-layers-of-keyword-arguments/21956/1 "2019-03-17T05:49:51Z")

</div>

Suppose that I have several functions where one calling another. The example below is arbitrary but in reality `foo2`, `foo3`, and `bar` need different keyword arguments. From a caller perspective, I can specify any keyword arguments and all of them flow through the chain.

```julia
foo1(x; kwargs...) = foo2(x; kwargs...)
foo2(x; kwargs...) = foo3(x; kwargs...)
foo3(x; kwargs...) = bar(x; kwargs...)

```

The problem is, the `bar` function (not owned by me) can only deal with its own recognized keyword arguments. Hence, it breaks when it sees additional ones that were only meant for `foo2` and `foo3`.

How do I fix this? I can write a function that extracts what I need in `foo2` and `foo3` and reconstruct `kwargs` along the way. Is there a better way?

---

<div class="post-metadata">

### Author: ![quinnj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/quinnj/32/11_2.png) [@quinnj](https://discourse.julialang.org/u/quinnj)
#### Post date: [March 17, 2019, 2:43pm UTC](https://discourse.julialang.org/t/several-layers-of-keyword-arguments/21956/2 "2019-03-17T14:43:01Z")

</div>

You could just write your own

```julia
bar_wrapper(args...; specific_keyword, kwargs...) = bar(args...; specific_keyword=specific_keyword)

```

And then call `bar_wrapper` from your code. I don’t see any reason that wouldn’t get fully inlined.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [March 17, 2019, 2:49pm UTC](https://discourse.julialang.org/t/several-layers-of-keyword-arguments/21956/3 "2019-03-17T14:49:54Z")

</div>

For call chains of medium complexity, I would wrap parameters in a `NamedTuple`, or a `struct` if things get more complex. Then everyone extracts what they need, and optionally you can provide an API with all the kwargs. Eg

```julia
foo_user(x; a = 1, b = 2) = foo1(x, (a = a, b = b))
foo1(x, params) = foo2(x, @show params)
foo2(x, params) = foo3(x, @show params)
foo3(x, params) = bar(x, @show params)
bar(x, params) = params.a + x # b ignored

```

then

```julia
julia> foo_user(1; a = 9, b = 3)
params = (a = 9, b = 3)
params = (a = 9, b = 3)
params = (a = 9, b = 3)
10

```

---

<div class="post-metadata">

### Author: ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)
#### Post date: [March 19, 2019, 5:25am UTC](https://discourse.julialang.org/t/several-layers-of-keyword-arguments/21956/4 "2019-03-19T05:25:42Z")

</div>

Nice! Just documenting the solution -

Problem:

```julia
julia> foo1(x; kwargs...) = foo2(x; kwargs...)
julia> foo2(x; kwargs...) = foo3(x; kwargs...)
julia> foo3(x; kwargs...) = bar(x; kwargs...)
julia> bar(x; kwargs...) = begin
         valid_keys = (:a, :b, :c)
         !all(map(x -> x ∈ valid_keys, keys(kwargs))) && error("invalid keyword args")
         true
       end
julia> foo1(1, d=1)
ERROR: invalid keyword args

```

Fix:

```julia
julia> foo3(x; d=1, kwargs...) = bar(x; kwargs...) # eats d
julia> foo1(1, d=1)
true

```
