The object is immutable if it cannot be modified after it’s creation. If the object can be modified, we say it is mutable.

In Swift we can create and use both, mutable and immutable objects by declaring variables using either var or let keyword.

var a = "mutable"
let b = "immutable"

a = "new value"
b = "new value" // Produces compile-time error

I think, there is no comprehensive list of immutable values applications. This topic is widely discussed across the internet and community. Different languages and even different coding styles can discover some benefits of immutable values using. The list of the benefits is long. It makes parallel processing and concurrent programming much easier, allows the last “before-the-crash” state logging, better error handling, reduces the “water ripple effect” when the single object state change changes global state (Side effects reduction). Though immutable data structure is never changed, you don’t need any error-prune copying before dealing with it. Access to immutables is lock-free e.t.c.

In two words - Immutable data structures makes the code better. Code is good, when it’s robust, reliable and reusable. Low Coupling and Referential Transparency are important “good code” characteristics, which are relatively easy affordable with immutables.

Low Coupling

Coupling is the measure of code dependency. We always want to reduce coupling and make our code components as much independent from each other as possible. The low coupling allows us to change the component without (or only with needed minimum) affecting another code components. The low-coupled code is easier to read because each component has it’s own, relatively small area of responsibility though you need to understand only this code, without spending time on figuring out how entire system works.

Immutability is our friend on the road to low coupling. Immutable data can be safely passed through different code blocks without worrying about it to be transformed and cause effects on the other parts of the code. Functional coding style means using of functions. Function transforms the data and returns the result without affecting the data (in most of the cases). So, if the function contains error, improper work or e.t.c., you know exactly where it is. Also, using functional code style and immutable data structures means, that you can significantly reduce object referencing.

The next tiny example shows the data transformation idea. We have immutable array numbers, and we need the sum of all even numbers it contains.

let numbers: [Int] = [1, 2, 3, 4, 5]
var evensSum = numbers.reduce(0){$0 + (($1 % 2 == 0) ? $1 : 0) }

// Obiviously, the numbers array is not changed, and can be passed to any other function
// without any side effects
print(numbers) // > [1, 2, 3, 4, 5]
// We got the desired result - we have the sum of 2 and 4 - all the evens in the `numbers` array
print(evensSum) // > 6

Functional programming is all about data transformation. In most of the cases - immutable data transformation. Using “in-place” transformation of the immutable data will help you to reduce coupling.

Referential transparency

Easily saying, Referential transparency means, that you can always replace function foo() with its return value without affection on programs behavior. From Andrew Birkett’s blog.

I also like the definition from the Haskel Wiki.

Referential transparency is an oft-touted property of (pure) functional languages, which makes it easier to reason about the behavior of programs. I don’t think there is any formal definition, but it usually means that an expression always evaluates to the same result in any context. Side effects like (uncontrolled) imperative update break this desirable property.

Referential transparency is a guarantee of code reusability. And, as you can understand, it denies the mutable state of data. If case of mutable state, two calls of the same function can potentially produce two different results. This case is bad for debugging and is error-prone. The developer can easily miss the state change and it will cause errors.

Conclusions

Wise use of the immutable data structures can significantly improve program reliability and code quality. It also helps to reduce coupling, makes code reusable and coding fun. In the end, it will reduce code maintenance and integration costs.