# Overload addition assignment += operator

**URL:** https://discourse.julialang.org/t/overload-addition-assignment-operator/28836
**Category:** New to Julia
**Created:** [September 17, 2019, 1:26am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836 "2019-09-17T01:26:57Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![milesf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milesf/32/9289_2.png) [@milesf](https://discourse.julialang.org/u/milesf)
#### Post date: [September 17, 2019, 1:26am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/1 "2019-09-17T01:26:57Z")

</div>

Here’s an example of what I’m trying to do:

```julia
struct MyStruct
    x::Int
end

function Base.:+(s::MyStruct, a::Int)
    MyStruct(s.x + a)
end

s1 = MyStruct(5)
s2 = s1 + 3

# ------ Everything above this line works ----------

# Attempting to create the following function produces:
# ERROR: UndefVarError: += not defined
function Base.:+=(s::MyStruct, a::Int)
    s.x + a
    s
end

s1 += 1

```

Wondering if this is possible. Seems that `+=` is treated differently than other operators. It can’t be found in REPL help.

```julia
help?> +=
search:

Couldn't find +=

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 17, 2019, 2:10am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/2 "2019-09-17T02:10:47Z")

</div>

`x += y` is a synonym for `x = x + y` in Julia, so you can’t overload it.

---

<div class="post-metadata">

### Author: ![milesf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milesf/32/9289_2.png) [@milesf](https://discourse.julialang.org/u/milesf)
#### Post date: [September 17, 2019, 2:13am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/3 "2019-09-17T02:13:32Z")

</div>

Thanks.  
There are some situations where it would be nice to modify a struct in-place, rather than create a copy.  
But for those situations, I guess I’ll just create a slightly less-elegant `add!` instead.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 17, 2019, 2:15am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/4 "2019-09-17T02:15:18Z")

</div>

> [@milesf](#):
>
> There are some situations where it would be nice to modify a struct in-place, rather than create a copy.

You could just do `s.x += 1`.

---

<div class="post-metadata">

### Author: ![milesf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milesf/32/9289_2.png) [@milesf](https://discourse.julialang.org/u/milesf)
#### Post date: [September 17, 2019, 2:17am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/5 "2019-09-17T02:17:01Z")

</div>

The `MyStruct` example was a trivial MWE.  
The real use case involves updating many (but not all) fields in less straightforward ways.

**Edit:**  
The specific use case is to overload the `*=` for [Factorization](https://github.com/JuliaMath/Primes.jl/blob/master/src/factorization.jl) so you can multiply factorizations together.

```julia
julia> f1 = Primes.factor(25)
5^2

julia> f2 = Primes.factor(36)
2^2 * 3^2

# ---- Would like to add the below capabilities -------
julia> f1 *= f2
2^2 * 3^2 * 5^2

# Looks like I'll have to settle for
julia> mul!(f1, f2)
2^2 * 3^2 * 5^2

```

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [September 17, 2019, 2:44am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/6 "2019-09-17T02:44:11Z")

</div>

`+=` or `*=` are not inplace operators (the LHS variable is assigned to and the object is not mutated). `.+=` and `.*=` are.

---

<div class="post-metadata">

### Author: ![milesf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milesf/32/9289_2.png) [@milesf](https://discourse.julialang.org/u/milesf)
#### Post date: [September 17, 2019, 3:43am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/7 "2019-09-17T03:43:29Z")

</div>

I assume .+= is not overloadable either.

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [September 17, 2019, 4:01am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/8 "2019-09-17T04:01:08Z")

</div>

Broadcast machinery can be overriden.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [September 17, 2019, 4:56am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/9 "2019-09-17T04:56:56Z")

</div>

> [@milesf](#):
>
> ```julia
> # ---- Would like to add the below capabilities ------- 
> julia> f1 *= f2 
> 2^2 * 3^2 * 5^2
> 
> ```

Wouldn’t this be type piracy?

**Edit:** well, unless you plan to contribute this functionality to the package itself, I guess.

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [September 17, 2019, 9:07am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/10 "2019-09-17T09:07:02Z")

</div>

You could try this package

> **[GitHub - jw3126/Setfield.jl: Update deeply nested immutable structs.](https://github.com/jw3126/Setfield.jl)**
>
> Update deeply nested immutable structs. Contribute to jw3126/Setfield.jl development by creating an account on GitHub.

It aims at helping with mutation of immutable structs

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 17, 2019, 1:47pm UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/11 "2019-09-17T13:47:20Z")

</div>

> [@milesf](#):
>
> It can’t be found in REPL help.

Would be good to fix this if anyone feels like patching the docs:

> <https://github.com/JuliaLang/julia/issues/33301>
>
> Operators like \`+=\` and dotted operators like \`.+\` currently don't have any REPL… help.

---

<div class="post-metadata">

### Author: ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)
#### Post date: [September 17, 2019, 1:56pm UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/12 "2019-09-17T13:56:45Z")

</div>

For an in-place calculation of a `mutable struct` (which I’d also like) it would be good to have `+=!` as a method.

---

<div class="post-metadata">

### Author: ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)
#### Post date: [September 18, 2019, 11:04pm UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/13 "2019-09-18T23:04:27Z")

</div>

> I assume .+= is not overloadable either.

Unfortunately not. For that kind of questions, use

```julia
julia> Meta.@lower a .+= b
:($(Expr(:thunk, CodeInfo(
1 ─ %1 = (Base.broadcasted)(+, a, b)
│ %2 = (Base.materialize!)(a, %1)
└── return %2
))))

```

So you would need to write a `materialize!` function that checks whether the dest is identical to one of the arguments of the broadcast, but you cannot dispatch on that.

`add!` or `mul!` is probably the way to go, with respect to naming.

---

<div class="post-metadata">

### Author: ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)
#### Post date: [September 19, 2019, 8:10am UTC](https://discourse.julialang.org/t/overload-addition-assignment-operator/28836/14 "2019-09-19T08:10:10Z")

</div>

What about ⇷? It looks kind of like a combination `+`-assignment operator.

```julia
julia> mutable struct Foo{T}
           a::T
       end

julia> function (⇷)(a::Foo{T}, b::T) where {T}
           a.a += b
       end
⇷ (generic function with 1 method)

julia> a = Foo(3)
Foo{Int64}(3)

julia> a ⇷ 3
6

julia> a ⇷ 3
9

julia> a ⇷ 3
12

julia> a
Foo{Int64}(12)

```

Type it with `\nvleftarrow` + TAB. It has an arrow’s precedence, which quick tests seems to suggest is lower than `+`/`-`. I think the [prec-names variable](https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm#L40) lists operator types in order from lowest to highest:

```julia
(define prec-names '(prec-assignment
                     prec-pair prec-conditional prec-arrow prec-lazy-or prec-lazy-and prec-comparison
                     prec-pipe< prec-pipe> prec-colon prec-plus prec-times prec-rational prec-bitshift
                     prec-power prec-decl prec-dot))

```

For reference, [here](https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm) are all the operators, and [here](https://docs.julialang.org/en/v0.6.0/manual/unicode-input/) are the unicode inputs and how to type them.
