# Preferred way to initialize read-only variable using mutations

**URL:** <https://discourse.julialang.org/t/preferred-way-to-initialize-read-only-variable-using-mutations/55504>\
**Category:** General Usage\
**Tags:** recommendations, function, discussion\
**Created:** [February 18, 2021, 2:15am UTC](https://discourse.julialang.org/t/preferred-way-to-initialize-read-only-variable-using-mutations/55504 "2021-02-18T02:15:17Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Uroc327](https://avatars.discourse-cdn.com/v4/letter/u/eb8c5e/32.png) [@Uroc327](https://discourse.julialang.org/u/Uroc327)\
**Post date:** [February 18, 2021, 2:15am UTC](https://discourse.julialang.org/t/preferred-way-to-initialize-read-only-variable-using-mutations/55504/1 "2021-02-18T02:15:17Z")

</div>

I wonder what your preferred ways of initializing a read-only variable using imperative code are. This becomes important, e.g., when there are closures involved and Julia wants to box the variable.

Something like

```julia
function g(x) = nothing # or something... who knows
function f(x::Integer, a::Integer)
    # Initialize y
    y = 1
    # let's pretend this sum can't be reformulated to something in closed form
    for i in 1:x
        y = y + i
    end

    # From this point on, y is basically constant
    # [...]
    sum(g(y + b) for b in 1:a)
end

```

My ideas were

```julia
function f(x, a)
    y = 1
    for i in 1:x
        y = y + i
    end

    let y = y
        sum(g(y + b) for b in 1:a)
    end
end

```

and

```julia
function f(x::Integer, a::Integer)
    y = begin 
        j = 1
        for i in 1:x
            j = j + i
        end
        j
    end

    sum(g(y + b) for b in 1:a)
end

```

I believe, those two variants should be equivalent. Although I am not completely certain. Personally I went with the first option, as it felt more concise to me.

What are your preferred ways of preventing a Box there and why?

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [February 18, 2021, 6:17pm UTC](https://discourse.julialang.org/t/preferred-way-to-initialize-read-only-variable-using-mutations/55504/2 "2021-02-18T18:17:19Z")

</div>

My preference is to write a specific function for initialization if possible. Out of the two proposed, the second feels “better”, only I’d write it as

```julia
    y = let y = 1
        for i in 1:x
            y = y + i
        end
        y
    end

```

There’s also the “Ref trick”:

```julia
function f(x::Integer, a::Integer)
    # Initialize y
    y = Ref(1)
    for i in 1:x
        y[] = y[] + i
    end

    sum(g(y[] + b) for b in 1:a)
end

```

Now, there is no binding change for `y`, so no boxing needed.

---

<div class="post-metadata">

**Author:** ![Uroc327](https://avatars.discourse-cdn.com/v4/letter/u/eb8c5e/32.png) [@Uroc327](https://discourse.julialang.org/u/Uroc327)\
**Post date:** [February 19, 2021, 3:54pm UTC](https://discourse.julialang.org/t/preferred-way-to-initialize-read-only-variable-using-mutations/55504/3 "2021-02-19T15:54:14Z")

</div>

Interesting. I didn’t know the `Ref` trick.

Is Julia able to use a plain value for `y`? In that case, `Ref(1)` would be quite different from `[1]`, right?

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [February 19, 2021, 9:18pm UTC](https://discourse.julialang.org/t/preferred-way-to-initialize-read-only-variable-using-mutations/55504/4 "2021-02-19T21:18:37Z")

</div>

Julia compiler is free to decide if a struct (mutable or not) is stack- or heap-allocated. `Ref(1)` can be stack allocated if the compiler can prove it is safe. My guess is that arrays cannot be stack allocated because they don’t have a fixed size. But heap allocation of a `Ref` must be cheaper than array, too, because arrays have to store more meta information.

In this case, `@btime` shows no allocations with `Ref` for simple initialization procedures, but switches to heap allocation if there’s something complicated in the loop. So, using one of your initial solutions is a faster way, and both seem equivalent in performance to me.

But `Ref` is useful if `y` has to be mutated inside the closure or if you want to share a mutable value between multiple closures.
