# Why tuples are immutable?

**URL:** <https://discourse.julialang.org/t/why-tuples-are-immutable/107071>\
**Category:** General Usage\
**Tags:** question\
**Created:** [December 3, 2023, 9:24am UTC](https://discourse.julialang.org/t/why-tuples-are-immutable/107071 "2023-12-03T09:24:58Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jiang\_ming\_zhang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jiang_ming_zhang/32/204063_2.png) [@jiang\_ming\_zhang](https://discourse.julialang.org/u/jiang_ming_zhang)\
**Post date:** [December 3, 2023, 9:24am UTC](https://discourse.julialang.org/t/why-tuples-are-immutable/107071/1 "2023-12-03T09:24:58Z")

</div>

What is the fundamental reason behind? Is it because the elements can be of any datatype, so modification incurs a lot of memory relocation?

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [December 3, 2023, 10:18am UTC](https://discourse.julialang.org/t/why-tuples-are-immutable/107071/2 "2023-12-03T10:18:47Z")

</div>

We need to understand what a `Tuple` is first.

```julia
help?> Tuple
search: Tuple tuple NTuple ntuple NamedTuple @NamedTuple

  Tuple{Types...}

  Tuples are an abstraction of the arguments of a function – without
  the function itself. The salient aspects of a function's arguments
  are their order and their types. Therefore a tuple type is similar
  to a parameterized immutable type where each parameter is the type
  of one field. Tuple types may have any number of parameters.

```

Since they represent the arguments of a function, we might think they are about to enter the function’s [stack](https://discourse.julialang.org/t/a-nice-explanation-of-memory-stack-vs-heap/53915). The stack is an abstract model for a processor’s register memory. Basically, the compiler needs to know a fixed size for all the arguments to create this stack of memory.

Moreover, immutability has a number of beneficial consequences. Immutable objects do not have to be copied when passed around. Also their known size and memory layout means they packed together efficiently or inlined into a larger structure.

Because of those benefits, immutable structs are the default in Julia. You can kne of the justifications why in the pull request below.

> <https://github.com/JuliaLang/julia/pull/20418>
>
> Fixes #19157.
> 
> This regularizes the type-defining keywords and makes them more… accurately descriptive. The proposed syntax is
> 
> \`\`\`
> abstract type Integer \<: Real end
> primitive type Int32 \<: Signed 32 end
> struct Complex ... end
> mutable struct Ref ... end
> \`\`\`
> 
> This is nicely extensible for the future, avoids stealing the words abstract, primitive, and (im)mutable as keywords, and as a bonus supports Compat.
> 
> 1. We should use the word \`struct\`; previously there was no keyword that described what the most common kind of user-defined type actually was.
> 2. We should steer people to immutable types by default. Immutable is generally better and faster, has better default behavior with \`===\`, and it's really pretty rare to need to update object fields. Base has many more immutable types than mutable, and in making this change it seemed to me that even more types could be made immutable. But \`type Foo\` looks more natural than \`immutable Foo\`, so \`type\` tends to be the default choice. This change reverses that, with \`struct Foo\` being more natural, and immutable. Writing \`mutable struct Foo\` makes you ask "does this really need to be mutable?", which is a good thing!
> 3. Immutable struct types are the closest thing we have to value type structs in other languages. We inline them in arrays in at least some cases, and being immutable makes it much harder to tell whether they are value or reference types.
> 4. FWIW, Rust also uses \`struct\` and makes them immutable. Not that we need to copy Rust, but it adds confidence that this is a reasonable thing to do.
> 5. We could eventually phase out mutable structs, and instead use \`Ref\` fields where needed in immutable structs.
> 
> So far I really like the way this change looks. \`immutable\` is kind of a long and ugly word.
> 
> The deprecation warning gives line numbers.
> 
> I haven't updated the manual yet. I think we'll want to reorganize it a bit to introduce immutable structs first.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [December 3, 2023, 1:30pm UTC](https://discourse.julialang.org/t/why-tuples-are-immutable/107071/4 "2023-12-03T13:30:26Z")

</div>

> [@mkitti](#):
>
> Since they represent the arguments of a function, we might think they are about to enter the function’s [stack](https://discourse.julialang.org/t/a-nice-explanation-of-memory-stack-vs-heap/53915). The stack is an abstract model for a processor’s register memory. Basically, the compiler needs to know a fixed size for all the arguments to create this stack of memory.

Stack and (im)mutability are orthogonal concepts with no connection.

EDIT:  
But I would add that true immutability is great for performance.  
True immutability requires some heavy handedness. Rust does this well:  
you can have either any number of immutable references to an object, or only a single mutable reference without any immutable references.  
Because of this, in Rust, if you have an immutable reference, you know for a fact that no mutable references exist.  
Without any mutable references existing, that thing really isn’t changing.

Julia takes a clunkier approach:  
This object type only allows immutable references, or this object type only allows mutable objects. So you need two mirrored object types if you want both, and then to convert between them, which unfortunately isn’t free even when in theory the compiler should be able to optimize the conversion away (but that can be fixed in the future!).

This is in contrast to C++ for example, which is like Rust but without the borrow checker that makes sure no mutable references exist when you have an immutable reference. Thus, in C++, an immutable object can change because you’re modifying a mutable view of that object.  
Rust disallows that because you can’t have both at the same time. Julia disallows that because for a particular object type, it is just either always immutable, or always mutable.

This lets the compiler optimize memory reads/writes.  
As a simple example, in Julia and Rust, the following code only needs 1 load and store, but in C++ you might need 2 loads:

```julia
x = immutable_object[i]
mutable_object[j] = x
foo(immutable_object[i])

```

because modifying `mutable_object` could be modifying `immutable_object` in C++, forcing the reload. Obviously, you should write

```julia
x = immutable_object[i]
mutable_object[j] = x
foo(x)

```

instead to avoid that problem, but that could be clunkier in more complicated examples (imagine: tons of abstractions/function calls that get inlined and compile down to something like the above).

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [December 3, 2023, 3:11pm UTC](https://discourse.julialang.org/t/why-tuples-are-immutable/107071/5 "2023-12-03T15:11:30Z")

</div>

> [@Elrod](#):
>
> Stack and (im)mutability are orthogonal concepts with no connection.

Sure, but you did not provide a better answer to the question: _Why are tuples immutable?_
