logo le blog invivoo blanc

Immutability and Javascript

14 August 2018 | Front-End, Java

The immutability is a very highly exploited concept in functional programming languages, where the values of the variables do not change when assigned. This has the merit of simplifying the administration of the application state by reducing the number of shared variables.
As we will see, immutables objects render more efficient MVC frameworks such as React and AngularJS. This is also why the word immutability is more and more commonly understood in the Javascript community. In this article, we will see the pros and cons of using immutables data structures in Javascript code.

Immutables objects to simplify the management of shared state

In the following example, we find two different ways to implement a multiply function by reusing a given sum function.

In the first example, the two functions share an acc accumulator where the intermediate States of the calculation are stored. And in the second, functions don’t share state, the acc variable is also used by the multiply function, but it’s private.

let acc = 0;

function multiply_1(a, b) {
    for(var i=0;i<a;++i) {
        sum(acc, b);
     }
}

function multiply_2(a, b) {
    let acc = 0;
    for(var i=0;i<a;++i) {
        acc = sum(acc, b);
    }
    return acc;
}

The example may seem simplistic, but we can compare the pros and cons of a shared-state approach (2) with a shared-state approach (1).

Advantages:

  • Each function is easier to understand because it uses only other public functions and its own private variables.
  • The code is easier to parallelize. For example, multiply calls can run in parallel, without the risk of interference. 

Disadvantages :

  • It takes more memory. Each function uses its acc accumulator, so the functional version requires twice as much memory as the imperative version.

A practical example of this kind of approach is in the use of state management frameworks, such as redux and streams.

  • The application state is stored in a single object, store, which cannot be edited directly.
  • To change the state of the application, you need a function, reducer, which takes as input a state and an action (an object that declaratively describes a change) and returns the following state in return.

Immutables objects to react to state changes faster

Currently, the majority of complex web applications are developed with the help of MVC frameworks such as React and AngularJS. Regardless of the chosen framework , they all require developers to clearly separate the model, view, and application controller. The model represents the state of UI, normally in the form of a POJO. The view represents the graphical display of the model, usually in the form of CSS and HTML. Finally, the controller represents the behavior of the application, usually in the form of Javascript code.
The framework is responsible for continuously updating the view from changes caused by the controller. The naïve approach is to regenerate the view after each change, which is very costly. To be more efficient, you have to be able to update only the parts of the view that have changed: so you have to be able to detect the changes in the model.

For a mutable view, to detect changes, there are two possible approaches:

  • Dirty checking, I. E. Recursively compare all two-state attributes – easy to implement, but not scalable if the state grows.
  • REACTIVE programming/Observer pattern, I. E. Listen to changes on each item and update the part of the associated page, making the framework behavior more difficult to understand.

In the case of a immutable view, the most important approach is called structural sharing. It will be illustrated with the following code:

var S0 = {
   name: 'John',
   address: {
      street: 'rue de Rivoli',
      city: 'Paris'
   }
};

changeName(state, newName) {
   return {
      name: newName,
      address: state.address
   };
}
S1 = changeName(S0, 'Mary');

In this example, in the application state, a name and an address are represented. The following figure shows the S0 and S1 states before and after the call to ChangeName.
For a name change, a function is implemented that, instead of changing a given state, builds a new version of the report with the new name. If one assumes that the state is a immutable object, one can compare its attributes by reference (i.e. with = = =) and thus perform much less operations compared to a classical recursive comparison.

To go further

In this article, we only gave a general view of the immutability, its pros and cons. In this section you will find articles to help you deepen your knowledge on the subject and tools, either present in the language or provided by libraries to create and manipulate immutable objects.

Reading on immutability

Functional Programming should be your #1 priority for 2015 – Functional programing, its advantages and disadvantages
Redux Prior Art – Introduce other approaches than redux
ImmutableJS et Structural sharing – Introduce ImmutableJS
Immutable Update Patterns  – Some recommendation for the updating of redux state