# Are immutable struct really immutable?

**URL:** <https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138>\
**Category:** General Usage\
**Created:** [July 8, 2019, 1:39pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138 "2019-07-08T13:39:47Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![fipelle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fipelle/32/4772_2.png) [@fipelle](https://discourse.julialang.org/u/fipelle)\
**Post date:** [July 8, 2019, 1:39pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/1 "2019-07-08T13:39:47Z")

</div>

Hi,

I recently realised that it is possible to edit the entries of an immutable struct as long as they are arrays. For example, by using the code:

```julia
struct MyStruct
    Y::Array{Float64,1}
end

# Define A
A = MyStruct(ones(10));

# Update A.Y
A.Y .+= rand(10);

```

I would like to understand why this is permitted. Working with an immutable struct, I would have expected to get an error (or at least a warning).

Would you please clarify that?

---

<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:** [July 8, 2019, 1:44pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/2 "2019-07-08T13:44:51Z")

</div>

The immutability isn’t recursive, but instead a property of the type itself… So its children are free to be mutable, hence you can put a mutable type (Vector in this case) into an immutable type and happily mutate them.

---

<div class="post-metadata">

**Author:** ![fipelle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fipelle/32/4772_2.png) [@fipelle](https://discourse.julialang.org/u/fipelle)\
**Post date:** [July 8, 2019, 1:48pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/3 "2019-07-08T13:48:12Z")

</div>

Right, but what is the advantage of a mutable struct vs an immutable struct if you can still mutate its elements? (I understand it does not work for all types, but it does work for many).

---

<div class="post-metadata">

**Author:** ![spaceLem](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/spacelem/32/217628_2.png) [@spaceLem](https://discourse.julialang.org/u/spaceLem)\
**Post date:** [July 8, 2019, 1:48pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/4 "2019-07-08T13:48:57Z")

</div>

Your struct `Y` is indeed immutable. It’s really just the pointer to an array that lives somewhere else on the heap, and that pointer can’t change (i.e. it can’t point to a different array). You can however modify the values in the array (to an extent), since it’s not actually in your struct.

So while you can write `A.Y .+= rand(10)`, you cannot write `A.Y = rand(10)`, since that would be create a new array and try to change what `Y` points to.

The array that `Y` points to lives on the heap, not the stack, and you don’t get the advantages that come with living on the stack.

---

<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:** [July 8, 2019, 1:49pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/5 "2019-07-08T13:49:01Z")

</div>

That you can’t mutate it’s fields?  
try:

```julia
A.Y = rand(10);

```

---

<div class="post-metadata">

**Author:** ![fipelle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fipelle/32/4772_2.png) [@fipelle](https://discourse.julialang.org/u/fipelle)\
**Post date:** [July 8, 2019, 1:57pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/6 "2019-07-08T13:57:19Z")

</div>

Thank you! This is clearer now.

However, I still have a doubt. Is there a way to recursively apply the immutability to struct elements?

---

<div class="post-metadata">

**Author:** ![spaceLem](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/spacelem/32/217628_2.png) [@spaceLem](https://discourse.julialang.org/u/spaceLem)\
**Post date:** [July 8, 2019, 1:58pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/7 "2019-07-08T13:58:51Z")

</div>

Maybe try using an `SArray` (from the `StaticArrays` package) rather than an `Array`.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [July 8, 2019, 2:15pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/8 "2019-07-08T14:15:51Z")

</div>

Note that while `StaticArray`s are indeed static and immutible, they are designed primarily for linear algebra efficiency on small arrays, not necessarily for “protecting” their contents. You might notice unnecessarily long compile times if you use them.

Julia, being true to its open nature, does not have any concept of “privacy”, even the immutability of `struct` is more for memory management than for immutability for its own sake.

If you want, you can build a custom immutable array type really easily

```julia
struct LockArray{T,N,V<:AbstractArray{T,N}} <: AbstractArray{T,N}
    data::V
end
 
Base.size(v::LockArray) = size(v.data)
Base.getindex(v::LockArray{T,N}, i::Vararg{Int,N}) where {T,N} = v.data[i...]        
function Base.setindex!(v::LockArray{T,N}, x, i::Vararg{Int,N}) where {T,N}
    throw(ArgumentError("Don't touch my array!!"))                 
end

```

```julia
julia> v = LockArray(rand(3,3,3));

julia> typeof(v)
LockArray{Float64,3,Array{Float64,3}}

julia> v[1,1,1] = Inf
ERROR: ArgumentError: Don't touch my array!!
Stacktrace:
 [1] setindex!(::LockArray{Float64,3,Array{Float64,3}}, ::Float64, ::Int64, ::Int64, ::Int64) at /home/msavas200/src/scrap.jl:9
 [2] top-level scope at none:0

```

More likely however, you’re much better off just not worrying about it at all.

---

<div class="post-metadata">

**Author:** ![fipelle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fipelle/32/4772_2.png) [@fipelle](https://discourse.julialang.org/u/fipelle)\
**Post date:** [July 8, 2019, 2:23pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/9 "2019-07-08T14:23:41Z")

</div>

Thank you!

`StaticArrays` might be useful for part of what I am doing (a forecasting package). However, I still want to make some of the elements of my structures to be private - at least for the sake of debugging.

It is probably a silly question, but: why do you need to define `Base.size` and `Base.getindex`? Isn’t `Base.setindex!` enough to make it private?

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [July 8, 2019, 2:37pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/10 "2019-07-08T14:37:19Z")

</div>

It’s just the minimal interface [to define an `AbstractArray` type](https://docs.julialang.org/en/v1.1/manual/interfaces/#man-interface-array-1). (In this case you are basically just telling it that the field you want to access is called `data`.)

Seriously though, nobody does this for debugging, I encourage you to save yourself some grief and just not worry about it. Be free!

You probably don’t want to use StaticArrays for forecasting, they are really designed for small arrays. If you try using them on giant arrays, the compiler will melt your CPU. (Though, depending on what you are doing, you might have an application for large `Array`s of `StaticArray`s.)

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [July 8, 2019, 2:41pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/11 "2019-07-08T14:41:55Z")

</div>

An immutable struct can be mutated because `typeof(X)` is mutable, so `typeof(X).mutable = true` works. But… don’t do this 😆.

---

<div class="post-metadata">

**Author:** ![fipelle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fipelle/32/4772_2.png) [@fipelle](https://discourse.julialang.org/u/fipelle)\
**Post date:** [July 8, 2019, 3:29pm UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/12 "2019-07-08T15:29:47Z")

</div>

@ExpandingMan Thank you for the suggestions. I might be overthinking it!

@ChrisRackauckas Yeah I do not like it either, it looks odd! 😆

---

<div class="post-metadata">

**Author:** ![colintbowers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/colintbowers/32/8033_2.png) [@colintbowers](https://discourse.julialang.org/u/colintbowers)\
**Post date:** [July 10, 2019, 12:21am UTC](https://discourse.julialang.org/t/are-immutable-struct-really-immutable/26138/13 "2019-07-10T00:21:00Z")

</div>

Just FYI, I asked a [similar question](https://stackoverflow.com/questions/27371153/understanding-immutable-composite-types-with-fields-of-mutable-types-in-julia) to this on StackOverflow when I was first starting out with Julia.
