<p>This means variables can't be overwritten, arrays can't be modified, and nothing can be modified &quot;in-place&quot; - a new variable has to be created. Or if you need to modify it with a loop, then you would need recursion or <code>foldl</code>/similar.</p>
<p>What are the advantages and disadvantages of complete immutability?</p>

<immutable>
What are the advantages and disadvantages of immutable languages?
CC BY-SA 4.0
2023-06-29T02:03:23.773Z
Close voters, what's your reasoning? This seems perfectly fine to me
rydwolf
CC BY-SA 4.0
2023-07-07T18:30:19.760Z
Don't you mean immutable *objects* rather than immutable *languages*?
dan04
CC BY-SA 4.0
2023-07-07T22:53:54.697Z
@dan04 The question appears to be about languages *in which all* objects are immutable.
Karl Knechtel
<p><strong>Advantages</strong>:</p>
<ul>
<li>Immutable objects can be shared, including partial sharing (like a sub string of string, or sub array of array). If the shared objects are large, depending on the task the performance may even improve.</li>
<li>Immutable objects can always be passed and returned by reference. A value returned by function can just change the ownership.</li>
<li>Immutable objects are multi-thread safe. Race condition happens when two threads modify the same object in an unsafe manner. It is not possible to modify an immutable object.</li>
</ul>
<p>Given array of floats of arbitrary size, how would you compute the sum of them?</p>
<pre><code>int sum(const std::vector&lt;int&gt; &amp; array, int p, int s) {
  return p == array.size() ? s : sum(array, p + 1, s + array[p]);
}

sum({1,2,4,8}, 0, 0) // it works, 15!
</code></pre>
<p>Mmm, does not this look a little bit too sophisticated? If not for you, go ahead with this idea. You can try to code this way without any special compiler, just accepting the agreed conventions.</p>
<p><strong>Challenges</strong></p>
<ul>
<li>This approach may create lots of short lived values. It is important to allocate and later discard them in a multi-thread friendly way. With many threads, a mutex on a memory manager may create performance bottleneck.</li>
<li>Security critical data structures (passwords, private keys and the like) should generally have they data &quot;shredded&quot; (overwritten, made inaccessible) as soon as no longer needed. An immutable object cannot be easily overwritten by the programmer, so the language must care to destroy it as soon as it goes out of scope. See <a href="https://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords">here</a>, for instance.</li>
</ul>

CC BY-SA 4.0
2023-07-07T17:24:29.640Z
2023-07-10T18:00:31.367Z
2023-07-10T18:00:31.367Z
Audrius Meškauskas
<h1>Disadvantage: Inefficient</h1>
<p>In order to modify a single element in an array with for example 1000 items, all 999 other items would need to be copied over into a brand new array. This would add considerable overhead and memory usage.</p>

CC BY-SA 4.0
2023-05-18T00:28:31.877Z
2023-05-18T00:28:31.877Z
CPlus
CC BY-SA 4.0
2023-05-18T00:29:40.197Z
It might be possible to implement them efficiently under the hood, although it might be prone to bugs. However, if you want to retain the original array in a separate variable, you have to copy it anyway.
naffetS
CC BY-SA 4.0
2023-05-18T00:32:29.110Z
For vectors that may be an issue, but for the far-more-commonly used (at least in general FP languages) linked list, CoW effectively solves that.
blueberry
CC BY-SA 4.0
2023-05-18T04:20:35.150Z
This is kind of a straw man argument; in a language with only immutable data structures, you probably would not use an array and copy the whole thing on every write. There are tree-based structures for persistent "arrays" which offer O(log n) performance for both reads and writes; typically the base of the logarithm is something like 32, so that the tree is at most 4 levels deep before you run out of memory anyway. There is still a significant overhead compared to mutable arrays, but it's not "copy the whole array on every write". See https://en.wikipedia.org/wiki/Persistent_data_structure
kaya3
CC BY-SA 4.0
2023-05-18T04:44:43.463Z
If all array members are immutable, copying the other 999 members to a new array is not overhead because we can still refer to those immutable members in the new array. Obviously, this depends on the language implementation. Some languages, like Ballerina, support this.
Hasitha Aravinda
CC BY-SA 4.0
2023-06-04T23:04:58.140Z
Your argument for inefficiency is the case of "[modifying] a single element in an array," but an immutable array _cannot_ be modified. This is a logical error. Even if you instead meant that _emulating_ mutation is inefficient, then this is unrelated to immutability for even in C that is an issue: sharing references to an array and having one modify it requires you to copy it to not be affected by that random mutation anyway. Either an object can be immutable, or it has to be copied, regardless of the language.
Longinus
CC BY-SA 4.0
2023-08-03T16:25:31.380Z
Because copying the whole array to change one item seems inefficient, probably other algorithms would be used. So one should rather compare solutions to problems. Are there problems solved more efficently with mutabilty?
Pablo H
<p>Two big advantages are <a href="https://en.wikipedia.org/wiki/Lazy_evaluation" rel="noreferrer">lazy evaluation</a> and <a href="https://en.wikipedia.org/wiki/Memoization" rel="noreferrer">memoisation</a>. If computations don't have side-effects, such as by mutating data structures, then you don't need to compute them at all when their results don't matter, and you don't need to recompute them multiple times when their results do matter.</p>

CC BY-SA 4.0
2023-05-18T04:25:07.563Z
2023-05-18T04:25:07.563Z
kaya3
<h1>Pro: Protection Against Accidental Mutations</h1>
<p>Sometimes you'll want to pass objects to other functions. And if a pass-by-reference system is used by your language, that object may end up having changes made to it (looking at you python and Java). Immutability ensures that if you do something like adding items to a list you pass to a function, the original list in the calling scope won't be changed.</p>

CC BY-SA 4.0
2023-05-18T00:29:50.873Z
2023-05-18T00:29:50.873Z
lyxal
CC BY-SA 4.0
2023-05-18T00:30:37.637Z
Being able to selectively protect against mutations (`const`) is what is ideal in my opinion.
CPlus
CC BY-SA 4.0
2023-05-18T00:32:01.880Z
But what if you don't know you need to have a const? Immutability provides blanket protection for the edge cases programmers haven't even thought about. There's been times I've been stung by mutability in places I thought there wouldn't have been a problem.
lyxal
CC BY-SA 4.0
2023-05-18T00:33:06.150Z
That's why as a habit I make everything `const` by default unless I explicitly know that I will need to modify it.
CPlus
CC BY-SA 4.0
2023-05-18T00:34:29.477Z
What about languages where you can't have a const? Like python which doesn't have a constant system at all.
lyxal
CC BY-SA 4.0
2023-05-18T00:35:36.663Z
That is the other extreme. Everything mutable. But on the other hand making all immutable is extreme too. That is why the optimal is simply having a `const`.
CPlus
CC BY-SA 4.0
2023-05-18T00:40:16.627Z
It does work better to have an option, you're right, but there is some advantages to all immutability
lyxal
CC BY-SA 4.0
2023-05-18T01:25:36.250Z
Some "immutable" langs like OCaml still have refs that are mutable. But I think it kind of contaminates the purity.
naffetS
CC BY-SA 4.0
2023-08-03T16:20:14.537Z
`const` and immutable are different: `const` is a promise _by_ the function that it won't modify the object, whereas immutable is (also) a promise _to_ the function that the object won't be modified. `const` is a constraint/guarantee for/about the function, immutable is (also) for the rest of the code.
Pablo H
<p>Programs that use mutability are easier to write, up to a certain level of complexity. You have an object that contains a value that's almost what you need, so you mutate the object and you move on.</p>
<p>But programmers spend a lot more time reading code than writing code. And reading code is harder than writing code. Reading code with mutable state is a lot harder than reading code without mutable state. If the language guarantees that no state is mutable, it's a huge cognitive win.</p>
<p>One thing that makes mutability especially painful is concurrency. When multiple threads can access the same memory, you risk a <a href="https://en.wikipedia.org/wiki/Race_condition" rel="noreferrer">race condition</a> each time the program reads or writes an object with mutable state. This makes even very simple reasoning about programs hard. Simple-looking code like</p>
<pre><code># x : integer
assert (x + x) mod 2 == 0
</code></pre>
<p>may be wrong if <code>x</code> is actually mutable by another thread.</p>
<p>This concern can be alleviated by making the language fully immutable. But outside of some special-purpose languages, programs have to deal with the mutability of the world around them — they have to handle input-ouput. So good languages <strong>make mutability explicit</strong>. For example, in Haskell, all mutability has to be handled through monad operations. In Rust, the type system keeps track of which objects are mutable and of which objects are potentially shared: the world is immutable by default. In Erlang, all local computation is immutable, except for interprocess communication and direct access to a single, compound mutable object (the process state).</p>

CC BY-SA 4.0
2023-05-18T22:45:26.767Z
2023-05-23T21:45:53.087Z
2023-05-23T21:45:53.087Z
Gilles 'SO- stop being evil'
# What are the advantages and disadvantages of immutable languages?
Posted by: username_0 on 2023-05-18
This means variables can't be overwritten, arrays can't be modified, and nothing can be modified "in-place" - a new variable has to be created. Or if you need to modify it with a loop, then you would need recursion or `foldl`/similar.

What are the advantages and disadvantages of complete immutability?
**Tags:** immutable
> **Comments:**
> **username_1**: Close voters, what's your reasoning? This seems perfectly fine to me  
> **username_2**: Don't you mean immutable *objects* rather than immutable *languages*?  
> **username_3**: @dan04 The question appears to be about languages *in which all* objects are immutable.  
---
## 5 answers
### Answer by username_11 on 2023-05-18. Score: 10
# Pro: Protection Against Accidental Mutations

Sometimes you'll want to pass objects to other functions. And if a pass-by-reference system is used by your language, that object may end up having changes made to it (looking at you python and Java). Immutability ensures that if you do something like adding items to a list you pass to a function, the original list in the calling scope won't be changed.
> **Comments:**
> **username_5** (2023-05-18): Being able to selectively protect against mutations (`const`) is what is ideal in my opinion.  
> **username_11** (2023-05-18): But what if you don't know you need to have a const? Immutability provides blanket protection for the edge cases programmers haven't even thought about. There's been times I've been stung by mutability in places I thought there wouldn't have been a problem.  
> **username_5** (2023-05-18): That's why as a habit I make everything `const` by default unless I explicitly know that I will need to modify it.  
> **username_11** (2023-05-18): What about languages where you can't have a const? Like python which doesn't have a constant system at all.  
> **username_5** (2023-05-18): That is the other extreme. Everything mutable. But on the other hand making all immutable is extreme too. That is why the optimal is simply having a `const`.  
> **username_11** (2023-05-18): It does work better to have an option, you're right, but there is some advantages to all immutability  
> **username_0** (2023-05-18): Some "immutable" langs like OCaml still have refs that are mutable. But I think it kind of contaminates the purity.  
> **username_10** (2023-08-03): `const` and immutable are different: `const` is a promise _by_ the function that it won't modify the object, whereas immutable is (also) a promise _to_ the function that the object won't be modified. `const` is a constraint/guarantee for/about the function, immutable is (also) for the rest of the code.  
---
### Answer by username_12 on 2023-05-18. Score: 9
Programs that use mutability are easier to write, up to a certain level of complexity. You have an object that contains a value that's almost what you need, so you mutate the object and you move on.
But programmers spend a lot more time reading code than writing code. And reading code is harder than writing code. Reading code with mutable state is a lot harder than reading code without mutable state. If the language guarantees that no state is mutable, it's a huge cognitive win.
One thing that makes mutability especially painful is concurrency. When multiple threads can access the same memory, you risk a race condition each time the program reads or writes an object with mutable state. This makes even very simple reasoning about programs hard. Simple-looking code like
# x : integer
assert (x + x) mod 2 == 0

may be wrong if x is actually mutable by another thread.
This concern can be alleviated by making the language fully immutable. But outside of some special-purpose languages, programs have to deal with the mutability of the world around them — they have to handle input-ouput. So good languages make mutability explicit. For example, in Haskell, all mutability has to be handled through monad operations. In Rust, the type system keeps track of which objects are mutable and of which objects are potentially shared: the world is immutable by default. In Erlang, all local computation is immutable, except for interprocess communication and direct access to a single, compound mutable object (the process state).
---
### Answer by username_7 on 2023-05-18. Score: 7
Two big advantages are [lazy evaluation](https://en.wikipedia.org/wiki/Lazy_evaluation) and [memoisation](https://en.wikipedia.org/wiki/Memoization). If computations don't have side-effects, such as by mutating data structures, then you don't need to compute them at all when their results don't matter, and you don't need to recompute them multiple times when their results do matter.
---
### Answer by username_4 on 2023-07-07. Score: 5
Advantages:

Immutable objects can be shared, including partial sharing (like a sub string of string, or sub array of array). If the shared objects are large, depending on the task the performance may even improve.
Immutable objects can always be passed and returned by reference. A value returned by function can just change the ownership.
Immutable objects are multi-thread safe. Race condition happens when two threads modify the same object in an unsafe manner. It is not possible to modify an immutable object.

Given array of floats of arbitrary size, how would you compute the sum of them?
int sum(const std::vector & array, int p, int s) {
  return p == array.size() ? s : sum(array, p + 1, s + array[p]);
}

sum({1,2,4,8}, 0, 0) // it works, 15!

Mmm, does not this look a little bit too sophisticated? If not for you, go ahead with this idea. You can try to code this way without any special compiler, just accepting the agreed conventions.
Challenges

This approach may create lots of short lived values. It is important to allocate and later discard them in a multi-thread friendly way. With many threads, a mutex on a memory manager may create performance bottleneck.
Security critical data structures (passwords, private keys and the like) should generally have they data "shredded" (overwritten, made inaccessible) as soon as no longer needed. An immutable object cannot be easily overwritten by the programmer, so the language must care to destroy it as soon as it goes out of scope. See here, for instance.
---
### Answer by username_5 on 2023-05-18. Score: 5
# Disadvantage: Inefficient

In order to modify a single element in an array with for example 1000 items, all 999 other items would need to be copied over into a brand new array. This would add considerable overhead and memory usage.
> **Comments:**
> **username_0** (2023-05-18): It might be possible to implement them efficiently under the hood, although it might be prone to bugs. However, if you want to retain the original array in a separate variable, you have to copy it anyway.  
> **username_6** (2023-05-18): For vectors that may be an issue, but for the far-more-commonly used (at least in general FP languages) linked list, CoW effectively solves that.  
> **username_7** (2023-05-18): This is kind of a straw man argument; in a language with only immutable data structures, you probably would not use an array and copy the whole thing on every write. There are tree-based structures for persistent "arrays" which offer O(log n) performance for both reads and writes; typically the base of the logarithm is something like 32, so that the tree is at most 4 levels deep before you run out of memory anyway. There is still a significant overhead compared to mutable arrays, but it's not "copy the whole array on every write". See https://en.wikipedia.org/wiki/Persistent_data_structure  
> **username_8** (2023-05-18): If all array members are immutable, copying the other 999 members to a new array is not overhead because we can still refer to those immutable members in the new array. Obviously, this depends on the language implementation. Some languages, like Ballerina, support this.  
> **username_9** (2023-06-04): Your argument for inefficiency is the case of "[modifying] a single element in an array," but an immutable array _cannot_ be modified. This is a logical error. Even if you instead meant that _emulating_ mutation is inefficient, then this is unrelated to immutability for even in C that is an issue: sharing references to an array and having one modify it requires you to copy it to not be affected by that random mutation anyway. Either an object can be immutable, or it has to be copied, regardless of the language.  
> **username_10** (2023-08-03): Because copying the whole array to change one item seems inefficient, probably other algorithms would be used. So one should rather compare solutions to problems. Are there problems solved more efficently with mutabilty?  
---
