# Questions with building a chainrules for mutating array function

**URL:** https://discourse.julialang.org/t/questions-with-building-a-chainrules-for-mutating-array-function/117237
**Category:** General Usage
**Tags:** zygote, chainrulescore, chainrules
**Created:** [July 19, 2024, 1:45pm UTC](https://discourse.julialang.org/t/questions-with-building-a-chainrules-for-mutating-array-function/117237 "2024-07-19T13:45:47Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![chooron](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chooron/32/208300_2.png) [@chooron](https://discourse.julialang.org/u/chooron)
#### Post date: [July 19, 2024, 1:45pm UTC](https://discourse.julialang.org/t/questions-with-building-a-chainrules-for-mutating-array-function/117237/1 "2024-07-19T13:45:47Z")

</div>

I want to build two functions for replacing values in a vector and an array, as shown below:

```julia
function mutate_vec(vec::AbstractVector{T}, new_value::T, idx::Int) where {T}
    vec[idx] = new_value
    vec
end

function mutate_arr(arr::AbstractArray{T}, new_value::AbstractArray{T}, idx::Tuple) where {T}
    arr[idx..., :] .= new_value
    arr
end

```

But it is known that Zygote usually does not support mutating arrays, so I wrote rrule rules for these two functions by following the guidelines from [Which functions need rules? · ChainRules](https://juliadiff.org/ChainRulesCore.jl/stable/rule_author/which_functions_need_rules.html#Which-functions-need-rules?), as shown below:

```julia
function ChainRules.rrule(::typeof(mutate_vec), vec::AbstractVector{T}, new_value::T, idx::Int) where {T}
    vec = mutate_vec(vec, new_value, idx)
    function mutate_vec_pullback(ȳ)
        return NoTangent(), ones(T, size(vec)), T(1.0), NoTangent()
    end
    return vec, mutate_vec_pullback
end

function ChainRules.rrule(::typeof(mutate_arr), arr::AbstractArray{T}, new_value::AbstractArray{T}, idx::Tuple) where {T}
    arr = mutate_arr(arr, new_value, idx)
    function mutate_arr_pullback(ȳ)
        return NoTangent(), ones(T, size(arr)), ones(T, size(new_value)), NoTangent()
    end
    return arr, mutate_arr_pullback
end

```

Due to my insufficient understanding of gradients, I am not sure if the rules I wrote are correct, so I hope someone can give me advice.

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [July 20, 2024, 9:16am UTC](https://discourse.julialang.org/t/questions-with-building-a-chainrules-for-mutating-array-function/117237/2 "2024-07-20T09:16:50Z")

</div>

Hi @chooron!

This could be more explicit in the ChainRules docs, but you must distinguish between two kinds of mutation:

1. mutation of objects created inside the function
2. mutation of objects passed as arguments to the function

The first kind of mutation is exactly what ChainRules allows you to solve with custom rules. However, the second kind is still experimental, and you need to take a look at [this documentation page](https://juliadiff.org/ChainRulesCore.jl/stable/rule_author/superpowers/mutation_support.html) to use it.

---

<div class="post-metadata">

### Author: ![chooron](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chooron/32/208300_2.png) [@chooron](https://discourse.julialang.org/u/chooron)
#### Post date: [July 22, 2024, 8:30am UTC](https://discourse.julialang.org/t/questions-with-building-a-chainrules-for-mutating-array-function/117237/3 "2024-07-22T08:30:42Z")

</div>

Sorry, I didn’t fully read this document, so I missed this part. Thank you very much for your suggestion. I will revise my code according to the document. 😊
