# Can Zygote do derivatives w.r.t. keyword arguments which get captured in \`kwargs...\`?

**URL:** https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553
**Category:** General Usage
**Created:** [February 13, 2020, 3:54am UTC](https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553 "2020-02-13T03:54:30Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [February 13, 2020, 3:54am UTC](https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553/1 "2020-02-13T03:54:30Z")

</div>

Zygote can do derivatives w.r.t. to keyword arguments, which is super cool:

```julia
foo(;x) = x^2
gradient(x -> foo(x=x), 2) # gives 4

```

In my case though, I’m doing some programatic stuff with the keywords of a certain function, so at some point I need to capture them all with a `kwargs...` then pass only some of them along to another function. A MWE of something like this is a function which accepts any keywords, but passes only the `x` keyword to another call. Here’s two ways I could think of writing this:

```julia
call_with_x_keyword_1(f; kwargs...) = f(;x=kwargs[:x])
call_with_x_keyword_2(f; kwargs...) = f(;(k=>v for (k,v) in kwargs if k==:x)...)

# both return 4, and ignore the `y` or any other keywords:
call_with_x_keyword_1(foo, x=2, y=3) 
call_with_x_keyword_2(foo, x=2, y=3) 

```

Unfortunately, Zygote can’t do these gradient for either one:

```julia
gradient(x -> call_with_x_keyword_1(foo, x=x), 2) # "mutating arrays is not supported"
gradient(x -> call_with_x_keyword_2(foo, x=x), 2) # "Need an adjoint for constructor Base.Iterators.Pairs{...}"

```

I’m wondering if there’s any suggestions for how to make this work (or maybe even if its possible at all)? The mutating array error is cryptic, I’m not sure where that would come in. I guess I could try and write that adjoint for `Base.Iterators.Pairs` but I’m having a hard time with where to even start with thinking about what the adjoint of that means. Finally, although I know that here I could do something like `foo(;x, ignored...) = x^2`, that doesn’t really work with my non-MWE example. Thanks for any help!

---

<div class="post-metadata">

### Author: ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)
#### Post date: [February 13, 2020, 4:07am UTC](https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553/2 "2020-02-13T04:07:31Z")

</div>

what about if you define a new funciton e.g.

```julia
bar(x) = foo(x=x)

```

---

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [February 13, 2020, 4:54am UTC](https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553/3 "2020-02-13T04:54:58Z")

</div>

Still an error, the problem I don’t think is in passing the argument, but rather in doing stuff with it from inside `kwargs`.

---

<div class="post-metadata">

### Author: ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)
#### Post date: [February 13, 2020, 5:15am UTC](https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553/4 "2020-02-13T05:15:10Z")

</div>

Works for me

```julia
foo(;x) = x^2
bar(x) = foo(x = x)

call_with_x(f, x) = f(x)

using Zygote

gradient(x -> call_with_x(bar, x), 2)

```

I have Julia 1.3.1 and Zygote 0.4.7.

I suspect the issue is your `call_with_x_keyword` function.

---

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [February 13, 2020, 5:30am UTC](https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553/5 "2020-02-13T05:30:55Z")

</div>

Oh thats what you were referring to, sorry. That’s not a solution for me since it does away entirely with capturing keywords as `kwargs...`, which in my case is the important piece that allows me to do some programatic things with the arguments (and is also the part Zygote is struggling on).

---

<div class="post-metadata">

### Author: ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)
#### Post date: [February 13, 2020, 5:59am UTC](https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553/6 "2020-02-13T05:59:34Z")

</div>

> [@marius311](#):
>
> some of them

Are these predetermined? E.g. they are always called `x`? Or is that variable?

---

<div class="post-metadata">

### Author: ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)
#### Post date: [February 13, 2020, 6:07am UTC](https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553/7 "2020-02-13T06:07:23Z")

</div>

This works for me if you know that `x` is always gonna be called `x`. See how I defined `foo2`

```julia
using Zygote

foo(;x) = x^2

foo2(;x, kwargs...) = foo(; x = x) # this will ignore all non `x` arguments.

gradient(x -> foo(x=x), 2) # gives 4

call_with_x_keyword_1(f; kwargs...) = f(;kwargs...)

gradient(x->call_with_x_keyword_1(foo; x = x), 2)

gradient(x->call_with_x_keyword_1(foo2; x = x), 2)

```

Or am I still not getting you?

I get that you want to differentatiate `foo(;x)` but `kwarg` can contain parameters named other than `x`, so you are doing `kwarg[:x]` (which I think is what Zygote does not support). But you can just break the `kwarg...` apart like `foo2(;x, kwargs) = foo(;x=x)`

---

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [February 13, 2020, 6:31pm UTC](https://discourse.julialang.org/t/can-zygote-do-derivatives-w-r-t-keyword-arguments-which-get-captured-in-kwargs/34553/8 "2020-02-13T18:31:18Z")

</div>

Unfortunately, like I mentioned in the original post,

> [@marius311](#):
>
> although I know that here I could do something like `foo(;x, ignored...) = x^2` , that doesn’t really work with my non-MWE example.
