# Partially mutable object

**URL:** <https://discourse.julialang.org/t/partially-mutable-object/70463>\
**Category:** New to Julia\
**Tags:** struct\
**Created:** [October 27, 2021, 9:30am UTC](https://discourse.julialang.org/t/partially-mutable-object/70463 "2021-10-27T09:30:26Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![whatsthecraic](https://avatars.discourse-cdn.com/v4/letter/w/7bcc69/32.png) [@whatsthecraic](https://discourse.julialang.org/u/whatsthecraic)\
**Post date:** [October 27, 2021, 9:30am UTC](https://discourse.julialang.org/t/partially-mutable-object/70463/1 "2021-10-27T09:30:26Z")

</div>

Can you only define some fields in an object constant or immutable, as in C++ `class Foo { int x; cont int y; };` ?

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [October 27, 2021, 10:36am UTC](https://discourse.julialang.org/t/partially-mutable-object/70463/2 "2021-10-27T10:36:02Z")

</div>

One thing you could do is define an immutable struct in which some of the (immutable) fields are wrapped in `Ref`s to make them mutable:

```julia
julia> struct Foo
           x :: Ref{Int}
           y :: Int
       end

julia> f = Foo(1, 2)
Foo(Base.RefValue{Int64}(1), 2)

julia> f.x[] += 10 # OK: mutate the Ref
11

julia> f.y += 10
ERROR: setfield! immutable struct of type Foo cannot be changed
Stacktrace:
 [1] setproperty!(x::Foo, f::Symbol, v::Int64)
   @ Base ./Base.jl:34
 [2] top-level scope
   @ REPL[4]:1

```

In terms of syntax, it does however change the way `Ref`-wrapped fields are accessed, since you have to put square brackets to access the value itself (`f.x[]` instead of simply `f.x` if it were directly an `Int`).

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [October 27, 2021, 12:34pm UTC](https://discourse.julialang.org/t/partially-mutable-object/70463/3 "2021-10-27T12:34:39Z")

</div>

Note that `Ref` is an abstract type:

```julia
julia> typeof(Ref(1))
Base.RefValue{Int64}

```

So for performance reasons you might want to use `Base.RefValue` instead.

---

<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:** [October 28, 2021, 4:49pm UTC](https://discourse.julialang.org/t/partially-mutable-object/70463/4 "2021-10-28T16:49:57Z")

</div>

The strict answer would be no, you can’t define some fields to be mutable because the concept of mutable types in Julia is different from C++.

But it is possible to make it look like that. One way is already mentioned, make “mutable” fields hold a container, another is to overload `setproperty!` for a mutable type so that it works only on certain fields:

```julia
struct SemiMutable1
    x::Base.RefValue{Int}
    y::Int
end

# to avoid [] for field access
function Base.getproperty(val::SemiMutable1, p::Symbol)
    if p === :x
        return getfield(val, :x)[]
    else
        return getfield(val, p)
    end
end

function Base.setproperty!(val::SemiMutable1, p::Symbol, x)
    if p === :x
        return getfield(val, :x)[] = x
    else
        return setfield!(val, p, x)
    end
end

mutable struct SemiMutable2
    x::Int
    y::Int
end

function Base.setproperty!(val::SemiMutable2, p::Symbol, x)
    if p === :x
        return setfield!(val, :x, x)
    else
        error("field `y` of `SemiMutable2` cannot be changed")
    end
end

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 28, 2021, 6:52pm UTC](https://discourse.julialang.org/t/partially-mutable-object/70463/5 "2021-10-28T18:52:58Z")

</div>

Here is a discussion of many alternatives: [Mutable scalar in immutable object: the best alternative?](https://discourse.julialang.org/t/mutable-scalar-in-immutable-object-the-best-alternative/57401)

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [October 28, 2021, 10:46pm UTC](https://discourse.julialang.org/t/partially-mutable-object/70463/6 "2021-10-28T22:46:05Z")

</div>

I understand your question, I’m just thinking is it a mistake or anti-pattern to ever do this? So do you have a more concrete example/reason to do this?

If it’s just out of curiosity, and possibly unfamiliarity with Julia (it’s not clear for how long you’ve used Julia), then FYI: `struct`s are immutable (by default) in Julia, ALSO, strictly, in the answers given. I used to like that Julia is an imperative language, i.e. not a pure functional by default.

Maybe @nben’s package can help you:

> [@Announcing Air.jl: STM and immutable collections](https://discourse.julialang.org/t/announcing-air-jl-stm-and-immutable-collections/70361):
>
> Air.jl is a new package for Julia that implements a number of composable multi-threading utilities largely inspired by paradigms from [Clojure](https://clojure.org/). These include: Immutable collections Persistent Dictionaries Persistent Sets Persistent N-Dimensional Arrays Persistent Weighted Dictionaries and Sets (which act as heaps, discrete distributions, and dictionaries/sets) Lazy Dictionaries A [Software Transactional Memory](https://en.wikipedia.org/wiki/Software_transactional_memory) system An asynchronous Actor type, based on [Clojure’s agents](https://clojure.org/reference/agents) A Volatile type that…

I can’t recommend Hickey’s talk highly enough on what’s wrong with almost all “information” systems (regarding what he calls place-oriented programming, which implies imperative, almost a synonym, it seems imperative is maybe more general, on how to implement the former).

> **[Keynote: The Value of Values](https://www.infoq.com/presentations/Value-Values/)**
>
> Rich Hickey compares value-oriented programming with place-oriented programming concluding that the time of imperative languages has passed and it is the time of functional programming.

If it seems long, or you only have a limited amount of time, I recommend giving it a change for even just the first 3-18 min. to see if it’s of interest.

I watched this talk recently, and then immediately again it’s that good, I would say required for all programmers. Note, do not watch it full-screen. I missed out on the slides the first time. That was only part of the reason to watch again, to check if I missed something there. I wouldn’t say it was needed, it was all very clear.

Julia immutable be default in lots of ways, strings, structs, but not arrays/containers, e.g. `Dict`s. but Air.jl fixes that for all (included in the standard library, in both missing mainly ordered `Dict`s), the important data structures and arrays

> [@whatsthecraic](#):
>
> in C++ `class Foo { int x; cont int y; };` ?

You have a typo cont-\>const, consider editing your post and doing this way:

```julia
julia> mutable struct Foo
           x::Int
           __y::Int
       end

```

Then x is mutable, more like in C++, while actually \_\_y too (but \_\_ prefix means stay away), i.e. the whole `struct`. Yes, that’s place-oriented-programming (PLOP)… what you aim for is only half that, a half-sin, and I’m not really sure it’s better. So also consider fully immutable, the default, that you can still use with arrays, but then again you’re back to PLOP. `PArray` would fix that.
