# How to mutate the value (not binding) of a scalar?

**URL:** https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607
**Category:** General Usage
**Tags:** question
**Created:** [November 1, 2022, 9:51am UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607 "2022-11-01T09:51:05Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)
#### Post date: [November 1, 2022, 9:51am UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607/1 "2022-11-01T09:51:05Z")

</div>

I can do the following to mutate the original memory,

```julia
w = ones(3)

 3-element Vector{Float64}:
 1.0
 1.0
 1.0

 x = w

 3-element Vector{Float64}:
 1.0
 1.0
 1.0

 x[2]=2.

 2.0

```

but I can’t find a way to mutate w if it’s a scalar,

```julia
1

 x=w

 1

 x=2

 2

 w

 1

```

I think I need this because I want to broadcast over a function that takes a scratch or work array, and I need to modify its contents. But maybe there is a different idiom that I can use.

---

<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: [November 1, 2022, 10:04am UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607/2 "2022-11-01T10:04:33Z")

</div>

There is no way to mutate the value of a scalar such as `1` or `1.0` - they are immutable objects of type `Int` and `Float64` respectively.

> [@prittjam](#):
>
> I think I need this because I want to broadcast over a function that takes a scratch or work array, and I need to modify its contents. But maybe there is a different idiom that I can use.

Can you expand on what you’re trying to do? There’s certainly a way achieve the same effect without trying to mutate immutables.

---

<div class="post-metadata">

### Author: ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)
#### Post date: [November 1, 2022, 10:06am UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607/3 "2022-11-01T10:06:06Z")

</div>

I’ve settled on this idiom, which is more elegant I think,

```julia
geman_mcclure(d2,s) = return one(s) / (one(s)+d2/s^2)^2
    
geman_mcclure!(d2,s,w) = @. w = geman_mcclure(d2,s)

```

---

<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: [November 1, 2022, 10:10am UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607/4 "2022-11-01T10:10:54Z")

</div>

I see - in julia, we’d typically have the mutated argument be the first argument of the function, so I’d write it like this:

```julia
geman_mcclure(d2, s) = one(s) / (one(s)+d2/s^2)^2
geman_mcclure!(w, d2, s) = geman_mcclure!(d2,s,w) = @. w = geman_mcclure(d2,s)

```

May I ask, what types do you expect to put into this? Is `d2` an array?

---

<div class="post-metadata">

### Author: ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)
#### Post date: [November 1, 2022, 10:12am UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607/5 "2022-11-01T10:12:10Z")

</div>

d2 and w are Vector{T \<: AbstractFloat}

---

<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: [November 1, 2022, 10:22am UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607/6 "2022-11-01T10:22:06Z")

</div>

Then I’d recommend implementing it like this:

```julia
function geman_mcclure!(w, d2, s)
    @. w = one(s) / (one(s) + d2 / s^2)^2
end
geman_mcclure(d2, s) = geman_cclure!(similar(d2), d2, s)

```

If `d2` for the non-mutating version is also expected to be a `Vector`, as otherwise the method won’t work:

```julia
julia> gm1(d2, s) = one(s) / (one(s)+d2/s^2)^2
gm1 (generic function with 1 method)

julia> gm1(rand(Float64, 10), rand(Float64))
ERROR: MethodError: no method matching +(::Float64, ::Vector{Float64})
For element-wise addition, use broadcasting with dot syntax: scalar .+ array

Closest candidates are:
  +(::Any, ::Any, ::Any, ::Any...)
   @ Base operators.jl:578
  +(::T, ::T) where T<:Union{Float16, Float32, Float64}
   @ Base float.jl:406
  +(::Union{Float16, Float32, Float64}, ::BigFloat)
   @ Base mpfr.jl:414
  ...

Stacktrace:
 [1] gm1(d2::Vector{Float64}, s::Float64)
   @ Main ./REPL[7]:1
 [2] top-level scope
   @ REPL[8]:1

```

Though usually, we try to avoid writing an explicitly vectorized function like `geman_mcclure!` and just directly use broadcasting inline, to allow for loop fusion to occur in longer chains (in which case your original scalar version is perfect already, and no other methods would be needed). It’s just a question of what you’d expect users to pass in.

---

<div class="post-metadata">

### Author: ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)
#### Post date: [November 1, 2022, 10:25am UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607/7 "2022-11-01T10:25:54Z")

</div>

Thanks for the tips, but I don’t understand your last comment. In this case, geman\_mcclure will be called with vectors of data passed in d2,s. Will broadcasting on the function allow the arithmetic operations to be fused? And can you give an example of what you mean by “broadcasting inline?”

And the non\_mutating versions can be scalars. I’m usually writing functions for scalars and broadcast over the function at the caller level. I try not to write vectorized code at the function level, but now I see how your suggestion can accommodate both types of calls. Thanks!

---

<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: [November 1, 2022, 11:15am UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607/8 "2022-11-01T11:15:19Z")

</div>

> [@prittjam](#):
>
> In this case, geman\_mcclure will be called with vectors of data passed in d2,s. Will broadcasting on the function allow the arithmetic operations to be fused?

Generally, yes - writing `geman_mcclure.(d2, s)` with `d2` a `Vector` and `s` a scalar (or even a vector of the same length as `d2`) is equivalent to

```julia
out_arr = similar(d2)
for i in eachindex(d2)
    out_arr[i] = geman_mcclure(d2[i], s) # geman_mcclure(d2[i], s[i]) if `s` is broadcastable
end
out_arr

```

which is the same as your explicitly vectorized `geman_mcclure!` function, modulo the additional allocation, which can be done ahead of time manually. If done ahead of time, you can (just with `geman_mcclure`) then write `w .= geman_mcclure.(d2, s)` , which is already equivalent to the loop above, except that `out_arr` does not have to be allocated, because it already exists.

This is a common pattern - instead of writing explicitly vectorized versions of scalar functions like `geman_mcclure!`, we usually only have the scalar version and broadcast/inplace-broadcast/map as necessary, allowing loop fusion to take place.

In comparison, `geman_mcclure!` does not allow loop fusion with broadcast outside of itself. That is, this example will not fuse loops:

```julia
z .= a .+ geman_mcclure!(w, ds2, s) 

```

(there will first be the inner loop inside of `geman_mcclure!`, then the outer one over `z` and `a`) whereas this will:

```julia
z .= a .+ geman_mcclure.(ds2, s)

```

which is in fact equivalent to

```julia
for idx in eachindex(z, a, ds2)
    z[idx] = a[idx] + geman_mcclure(ds2[idx], s)
end

```

This is also what I mean with “broadcasting inline” - simply using the scalar version in a broadcast is more flexible than having `geman_mcclure!`, which is required to complete before the outer broadcast can be calculated. The general rule of thumb for when I use explicitly modifying functions is either when the operation is not a scalar operation (i.e., more than a single index is required to perform the calculation, forcing you to write a loop either way) or when there’s a truly persistent modification of a datastructure as a sideeffect happens, e.g. with `get!`:

```julia
help?> get!
search: get! mergewith! get getpid getkey getfield getindex getglobal

  get!(collection, key, default)

  Return the value stored for the given key, or if no mapping for the
  key is present, store key => default, and return default.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> d = Dict("a"=>1, "b"=>2, "c"=>3);
  
  julia> get!(d, "a", 5)
  1
  
  julia> get!(d, "d", 4)
  4
  
  julia> d
  Dict{String, Int64} with 4 entries:
    "c" => 3
    "b" => 2
    "a" => 1
    "d" => 4

```

---

<div class="post-metadata">

### Author: ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)
#### Post date: [November 1, 2022, 12:45pm UTC](https://discourse.julialang.org/t/how-to-mutate-the-value-not-binding-of-a-scalar/89607/9 "2022-11-01T12:45:42Z")

</div>

Thanks for the helpful discussion!
