Hero image

Immutability


The first thing to know about functional programming is Immutability.

What is it?

At the core its goal is to make change impossible where you do not expect it.

A problem that developers often run into is that they cannot tell where a variable has changed, or aren’t certain how a value came to be. Now you might think that it is not an issue, and perhaps for small progams it isn’t, but once there are many people working on software over years things are not so simple. Once features have been reworked by different teams and developers it is nice to be assured you know exactly what is happening to your variables at any point in time.

The Pros

  1. You 100% know the state of your code at any point, as variables cannot be changed after they are initially set. This includes 3rd party libraries, where you don’t have to worry about functions changing your objects.
  2. The code is more maintainable - It is always good to think about people in the future looking after you code.

The Cons

Like most things, there are situations where the concept doesn’t work and in these cases it might be best to use mutable variables instead.

  1. Performance - There is a small performance cost to creating many immutable structures rather than a single mutable variable.
  2. Some data structures are much harder to create.

The Syntax

There are two different types of syntax used in javascript for immutability. One is for primitives and references, and the other is for object properties. We will assume all code in this article is in strict mode.

JS
Typescript

How to use

Below I have details some common problems that use mutations and how they can be achieved with immutable code.

Finding elements of an array

How to start with an array of items, and remove any that do not match the criteria you are looking for.

JS
Typescript
Mutation
Immutable
let fruits = [
    { type: 'Apple', nice: true},
    { type: 'Banana', nice: false},
    { type: 'Mango', nice: true}
];

// This is bad practice in general, at it changes
// and array as we are iterating it.
fruits.forEach((fruit, index) => {
    if (!fruit.nice) {
        fruits.splice(index, 1);
    }
})
const fruits = [
    { type: 'Apple', nice: true},
    { type: 'Banana', nice: false},
    { type: 'Mango', nice: true}
];

const niceFruits = fruits.filter((fruit) => !fruit.nice);

Removing keys from an object

It is common to want to return only a subset of the data you have from your API. This is probably best done by tools such as GraphQL, $project in mongodb, SELECT statements in SQL, but it is not uncommon to do the same thing in code.

JS
Typescript
Mutation
Immutable
function removeKeyFromObject(key, obj) {
    delete obj[key];
}

const user = {
    username: "my-username",
    password: "secret",
};

removeKeyFromObject("password", user);

// user = { username: "my-username" }
function removeKeyFromObject(key, obj) {
    const {[key]: propToDelete, ...newObj} = obj
    return newObj;
}

const user = {
    username: "my-username",
    password: "secret",
};

const userWithoutPassword
    = removeKeyFromObject("password", user);

// userWithoutPassword = { username: "my-username" }


What to read more? Check out more posts below!