# Mutable struct vs closure

**URL:** <https://discourse.julialang.org/t/mutable-struct-vs-closure/20233>\
**Category:** New to Julia\
**Tags:** struct, closure\
**Created:** [January 29, 2019, 2:17pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233 "2019-01-29T14:17:03Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [January 29, 2019, 2:17pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/1 "2019-01-29T14:17:04Z")

</div>

hello, suppose that I would like to maintain a vector that would be lengthened or shortened over time. Immutable struct could not do the job, so I need to use mutable struct. Then I need to build some methods that takes the mutable struct type as argument, e.g. `shortened!(obj)`, `lengthen!(obj, x)`.

Another way is to make the vector as a closure variable and returning closures like `get()`, `shortened()` and `lengthen(x)`.

which approach is preferred? seems like the closure approach is more like traditional OOP, but it’s seldomly covered in Julia docs.

please discuss. thanks.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 29, 2019, 2:23pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/2 "2019-01-29T14:23:17Z")

</div>

It’s not very clear what you want. Could you please give more details? Eg. Why doesn’t Julia’s `Vector` type do what you want?

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [January 29, 2019, 2:39pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/3 "2019-01-29T14:39:17Z")

</div>

for this particular example, yes, `Vector` would do.

But what I concern is to have an “object” that has some fields that _changes_ over time. Then, there’re two ways doing that: define a `mutable struct` type and define `!` methods for the type; or, use closures.

The closure approach, which seems unpopular in `Julia`, seems to give better “encapsulation”, because the captured variables could only be access thru the closures returned.

Or, is it a better “think Julia” way to do this?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 29, 2019, 2:44pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/4 "2019-01-29T14:44:23Z")

</div>

> [@tomtom](#):
>
> The closure approach, which seems unpopular in `Julia` , seems to give better “encapsulation”, because the captured variables could only be access thru the closures returned.

I would not worry about this. Simply adopt the habit that you only use accessor functions (which you need to define, and consider part of the interface), not fields directly. A `mutable struct` is easier to document, debug, dispatch on, etc.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [January 29, 2019, 2:51pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/5 "2019-01-29T14:51:53Z")

</div>

a simple example below to illustrate the idea:

```julia
###########################
# mutable struct approach
mutable struct CounterType
    count::Int64
end

function add1!(x::CounterType)
    x.count += 1
end

function minus1!(x::CounterType)
    x.count -= 1
end

###########################
# closure approach
function Counter(init::Int64)
    _count = init

    function get()
        return _count
    end

    function add1()
        _count += 1
    end

    function minus1()
        _count -= 1
    end

    return (get = get,
            add1 = add1,
            minus1 = minus1)
end

```

Now, both approaches would do the job:

```julia
julia> c = CounterType(3)
CounterType(3)
julia> c.count
3
julia> add1!(c)
4
julia> c.count
4
julia> minus1!(c)
3
julia> c.count
3

julia> (get, add1, minus1) = Counter(3)
(get = get, add1 = add1, minus1 = minus1)
julia> get()
3
julia> add1()
4
julia> get()
4
julia> minus1()
3
julia> get()
3

```

which approach **should** I use in general? I know that the `mutable struct` is more “Julia”-like, but as the fields are mutable, I just feel more “dangerous” as there’s no “encapsulation”…

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [January 29, 2019, 2:54pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/6 "2019-01-29T14:54:05Z")

</div>

> [@tomtom](#):
>
> But what I concern is to have an “object” that has some fields that _changes_ over time.

> [@tomtom](#):
>
> suppose that I would like to maintain a vector that would be lengthened or shortened over time. Immutable struct could not do the job, so I need to use mutable struct.

Not sure if I understand you correctly, but that seems like a wrong statement!

```Julia
struct Test
   unchanging::Vector{Int}
end
x = Test([2,3,4])
resize!(x.unchanging, 10)

```

unchanging still refers to the same vector, only the mutable object itself changed - which is a very idiomatic way to encapsulate mutability 😉  
This is also idiomatic, especially if only few fields need mutability:

```Julia
struct Test
   value::Ref{Int}
end
x = Test(Ref(1))
x.value[] = 2
x.value[] == 2

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 29, 2019, 2:56pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/7 "2019-01-29T14:56:10Z")

</div>

> [@tomtom](#):
>
> I just feel more “dangerous”

I don’t see why this should be.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [January 29, 2019, 3:02pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/8 "2019-01-29T15:02:02Z")

</div>

because any method could modify the contents in a `mutable struct`.

while in the closure approach, the captured variables could only be accessed thru the closures given.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 29, 2019, 3:37pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/9 "2019-01-29T15:37:38Z")

</div>

> while in the closure approach, the captured variables could only be accessed thru the closures given.

This is not true:

```julia
(get, add1, minus1) = Counter(3)

julia> a = get._count
Core.Box(3)

julia> a.contents
3

julia> a.contents = 4
4

julia> get()
4

```

Note that a closure is implemented as a struct. (Note also that `Core.Box` is bad news, related to a nasty issue about inference for closures.)

In my opinion the most “Julian” is probably a normal (immutable) `struct`:

```julia
struct MyCounter
    a::Int 
end 

my_add(x::MyCounter) = MyCounter(x.a + 1)

x = MyCounter(3)
my_add(x)

```

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [January 29, 2019, 4:14pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/10 "2019-01-29T16:14:11Z")

</div>

If you really want encapsulation it is possible to overload `getproperty` and `setproperty!`

```julia
julia> mutable struct CounterType
           count::Int64
       end

julia> Base.getproperty(x::CounterType,::Symbol) = error("private fields")

julia> Base.setproperty!(x::CounterType,::Symbol,::Any) = error("cannot set private field")

julia> Base.propertynames(x::CounterType) = ()

```

This prevents the fields from being accessed or set with the dot notation for accessing fields.

```julia
julia> a = CounterType(5)
CounterType(5)

julia> a.count
ERROR: private fields
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] getproperty(::CounterType, ::Symbol) at ./REPL[2]:1

```

getters and setters can then be constructed

```julia
julia> get(x::CounterType) = getfield(x,:count)
get (generic function with 1 method)

julia> set(x::CounterType,y::Int) = setfield!(x,:count,y)
set (generic function with 1 method)

julia> function minus1!(x::CounterType)
           set(x, get(x) -1)
       end
minus1! (generic function with 1 method)

julia> function add1!(x::CounterType)
           set(x,get(x) + 1)
       end
add1! (generic function with 1 method)

julia> add1!(a)
6

julia> add1!(a)
7

julia> minus1!(a)
6

```

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [January 29, 2019, 4:17pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/11 "2019-01-29T16:17:55Z")

</div>

thanks.

after some trial-and-error, the following avoids:

1. `Core.Box`
2. accessing captured variables except using closures provided

```julia
function Counter(init::Int64)::NamedTuple{(:get, :add1, :minus1),
                                            NTuple{3, Function} }
    _count = Vector{Int64}(undef, 1)
    _count[1] = init

    local get, add1, minus1
    let _count = _count

    function get()::Int64
        return _count[1]
    end

    function add1()::Nothing
        _count[1] += 1
        return nothing
    end

    function minus1()::Nothing
        _count[1] -= 1
        return nothing
    end

    end

    return (get = get,
            add1 = add1,
            minus1 = minus1)
end

@code_warntype Counter(3) # fine

julia> get._count
ERROR: type #get#38 has no field _count

```

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 29, 2019, 5:17pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/12 "2019-01-29T17:17:38Z")

</div>

You can also reduce this to

```julia
julia> let count = 0
            global function add1()
                count += 1
             end
           end
add1 (generic function with 1 method)

julia> add1()
1

julia> add1()
2

```

---

<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:** [January 29, 2019, 6:24pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/13 "2019-01-29T18:24:59Z")

</div>

> [@WschW](#):
>
> If you really want encapsulation it is possible to overload `getproperty` and `setproperty!`

This does obfuscate it more, but you can always still use `getfield` method to access it anyway.

```Julia
julia> getfield(get,:_count)
Core.Box(3)

```

---

<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:** [January 29, 2019, 6:34pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/14 "2019-01-29T18:34:08Z")

</div>

You need to understand that closures are not a first class concept in julia, they are implemented as structs during lowering. They are mere syntactic sugar above callable structs. All the encapsulation through closures is a mirage.

The only question is: What is the most transparent and friendly way of obtaining the desired interface and `@code_native`?

Once you are willing to spend the time to think about what you are writing (instead of having a one-liner just work, which is admittedly awesome), closures are useless, and explicit (mutable or immutable) structs always win.

Your latest closure/Vector-based variant introduces multiple useless pointer indirections plus wasted memory.

Hence, `mutable struct Counter _cnt::Int64 end` should be the thing, plus documentation that the internal layout of `Counter` is not part of the stable API. If any downstream users of your code still use the internal layout, well, they have been warned.

Nannying your downstream by `Base.getproperty(::Counter, args...) = error("don't access me")` and `Base.setproperty!(::Counter, args...)=error("don't access! me")` is imo just mean.

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [January 29, 2019, 7:08pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/15 "2019-01-29T19:08:28Z")

</div>

> [@chakravala](#):
>
> This does obfuscate it more, but you can always still use `getfield` method to access it anyway.

In the same sense you can do the same in other languages with “private” fields, for example in C++ you can cast it to `char *`. The point of encapsulation seems more about making it difficult to **accidentally** modify/observe a `private` field then about guarantees that a “non-member” function can’t be made that can access it.

Also your code example seems to be based on a different attempt at encapsulation, my example does not use `Core.Box`, nor has a field with the name `:_count`

```julia
julia> getfield(get,:_count)
ERROR: type #get has no field _count
Stacktrace:
 [1] top-level scope at none:0

julia> getfield(a,:count)
5

julia> @code_typed get(a)
CodeInfo(
1 ─ %1 = (Main.getfield)(x, :count)::Int64
└── return %1
) => Int64

```

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [January 29, 2019, 7:28pm UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/16 "2019-01-29T19:28:58Z")

</div>

The main disadvantage I see with `mutable struct` is that its state can change, so it makes code more complicated to reason about, and less safe. This closure approach does not seem to address that, in fact it makes it easy to create bugs like this:

```julia
# a function intended to return a counter starting at 100
const COUNTER_100 = Counter(100)
get_counter_100() = COUNTER_100

# testing the above function
c = get_counter_100()
c.get() # returns 100
c.add1()
c.get() # returns 101

# testing it again
d = get_counter_100()
d.get() # oops! returns 101

```

Furthermore, the closure approach may lead to code like this:

```julia
(get, add1, minus1) = Counter(3)

```

which is not good. Whenever you change the signature of `Counter` in the future, e.g. to return more functions, you’ll need to find and update every line like this.

As others have pointed out, the closure approach is also harder to work with, less readable, and less efficient. So overall, I don’t really see any advantages of using it, and I would go with either an immutable struct just like in @dpsanders post above (creating a new instance for each modification) if you want the advantages of immutability, or simply a `mutable struct`.

I’m curious though where you got the idea, have you worked with languages/frameworks where this particular closure-based pattern is preferred? Anything you can link to?

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [January 30, 2019, 1:38am UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/17 "2019-01-30T01:38:24Z")

</div>

> [@bennedich](#):
>
> have you worked with languages/frameworks where this particular closure-based pattern is preferred?

haha, we’re all “old” guys in this forum I guess. I used to code in C, C++, Java, R…

as @WschW has mentioned, traditional OO supports “private” fields, and methods “belong” to a “class”. The type system in `julia` is a new concept for me… I still feel “dangerous” using the `mutable struct` way…

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [January 30, 2019, 3:52am UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/18 "2019-01-30T03:52:13Z")

</div>

> [@dpsanders](#):
>
> In my opinion the most “Julian” is probably a normal (immutable) `struct` :

this does not work well if the type is composite. For example:

```julia
struct Composite
    smallest::Int64
    largest::Int64
    values::Vector{Int64}

    function Composite(x::Vector{Int64})
        new(minimum(x), maximum(x), x)
    end
end

function newelement(c::Composite, x::Int64)::Composite
    return Composite([c.values; x])
end

julia> a = Composite([2, 3, 5])
Composite(2, 5, [2, 3, 5])

julia> b = newelement(a, 1)
Composite(1, 5, [2, 3, 5, 1])

```

as the composite type contains a non-scalar field (i.e., `values`), every new Instantiation of this immutable type would result in **memory allocation** …

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 30, 2019, 7:48am UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/19 "2019-01-30T07:48:41Z")

</div>

> [@tomtom](#):
>
> every new Instantiation of this immutable type would result in **memory allocation** …

… which may or may not be the bottleneck in particular code, so worrying about it prematurely does not always pay off.

Also, if you happen to be accumulating an _ex ante_ unknown number of elements, you cannot always avoid _some_ memory allocation.

The best approach is to design a small interface, which provides a layer over the actual mechanism. You can benchmark and optimize the latter, and change it without affecting the rest of the code.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [January 30, 2019, 10:53am UTC](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233/20 "2019-01-30T10:53:22Z")

</div>

I think, it’s worth discussing and thinking deeply on the tradeoffs between the flexibility of `mutable struct` and the benefits of traditional encapsulation.

[Next page](https://discourse.julialang.org/t/mutable-struct-vs-closure/20233.md?page=2)
