Immutability

Before we discuss immutability, let's start by answering a question:

What datatype is more secure to work with in a multithreaded environment?

Let me try to explain the question with the help of an example—suppose you had a variable dictionary of position coordinates:

var locationDictionary = ["latitude": 131.93839, "longitude": 32.83838]

locationDictionary is the location of the user that gets populated once every five minutes; this locationDictionary will, at some time in the near future, be converted to a locations JSON object and synced to the backend (an API pushing data to the server) from where the location will be picked and shown to some web view or it may be used for any other real-time location update purpose.

Imagine working with this location dictionary in a multithreaded environment; since it is a variable, locationDictionary can be updated anytime by any thread at any given moment in time, resulting in faulty location updates. You might end up sending unwanted or corrupt data to your API.

Simple fix: Make the variable a constant, and you can rest assured that once the value is populated in the dictionary, it will not be altered and hence you will have reliable results.

From the preceding discussion, we can now define an immutable object and what a mutable object is: an immutable object is an object that cannot be changed over the course of its existence or scope, whereas a mutable object can be changed within its scope.

Functional programming promotes the concept of immutability; remember the example:

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let numbersLessThanFive = numbers.filter { $0 < 5 }

Did you note how we can create a new numbersLessThanFive array as a constant rather then a variable? Try creating a similar array with imperative programming; can you have a constant array ? Let's try doing that:

var numbersLessThanFive = [Int]()
for index in 0..< numbers.count
{
if numbers[index] > 5
{
numbersLessThanFive.append(numbers[index])
}
}

The process is not only wordy but involves lossy data flow in the program, as any other thread executing in the memory can now change the values in this array since the array is now a variable. Working with immutable data streams is encouraged in any programming language, especially when you are trying to build complex applications that might spawn myriads of threads:

Since one aspect of functional reactive programming comprises a lot of functional programming, working with immutable data comes naturally while modeling logic in the FRP way and hence half the problems are addressed from the start. Well it is not as simple as it looks, but constant practice will make you perfect; this is the reason I encourage you not to miss any chapter or topic in this book, as each topic builds on top of another and strengthens your knowledge of FRP as a whole.

Since immutable objects cannot be changed over time during execution, it means they come at an cost and might not be reusable in certain scenarios. You have to dispose an immutable object or populate a new one if the current one does not fit the context. As you can see, there are certain drawbacks while working with immutable data types, but as intelligent programmers, we need to strike the right balance and make logical choices while modeling our data types:

From the preceding diagram and our previous discussion, it is quite clear why working with mutable state can cause non-deterministic behavior in your program code. As mentioned earlier, we need to strike a balance between both to maintain a shared state to suit the problem at hand. More immutable data types mean more deterministic behavior.