Alexander Kondov

@KondovAlexander

Functional programming paradigms in modern JavaScript: Immutability

This is the second chapter in a series of articles on practical Functional Programming paradigms. If you haven’t read the previous chapters you can start from here.

This article will be concentrated on another of the fundamental topics that every functional programmer must understand deeply — immutability. More specifically — it’s applications in modern JavaScript development.

What does immutability mean? The definition that you can see in Wikipedia states that an immutable object is one whose state cannot be modified after it is created. Or in other words some variable that can’t change it’s value.

The first time I encountered immutability I read the definition more than once in order to make sure I’ve read it correctly. How can I program with variables that never change their values? To me this was incredibly counterintuitive.

Nowadays we should be focusing more and more on the developer experience. With that I mean that code should be written in such a manner that it will be easily understood by the next developer. And this is exactly where immutability kicks in.

The more I read about functional programming the more I understood it’s actual goal. If you think about it, people have been writing programs for a long time and a solid part of them are written in a non-functional manner.

Chances are that if you are a web developer you will encounter more programs written without the use of FP practices. So why should you be investing the time in learning about this esoteric programming paradigm?

Functional programming’s goal is to allow us to think less and write more descriptive code.

You have probably been in a situation in which you were tracking a variable along the lines of a JavaScript file, desperately trying to find the exact line at which it turns into undefined.

This is what I meant when I said that FP allows us to think less. When a variable is defined it is given some value and this value will never change. Period.

It will also lower the lifespan of your separate variables. This is the number of lines in which a variable is used since it’s declaration.

Much like we discussed in the previous chapter with pure functions — you won’t be able to have all of our variables immutable and this is okay.

Functional programming is not something that you should put before the quality of your code. FP’s purpose is to help us write better and cleaner code, so if your code would be much cleaner and easier to understand if you mutate a variable then so be it.

In the rest of the article we will look into how we can put this into practice in modern programs written with JavaScript.

You’ve been using immutability

When we are talking about immutability we are stressing too much on the variable side of things. How we shouldn’t be reassigning values. While in fact we should be paying more attention to our functions and writing them with immutability in mind.

The goal of this series of articles is to point how functional programming patterns are used in In fact you’ve encountered immutability in your everyday JavaScript coding but you probably haven’t paid that much attention to it. Let’s examine some of the built in functions in the language.

As you can see, those functions do not modify the caller of the function. Each of those functions return an entirely new value, without modifying the object on which they are called. The same behaviour can be observed with many other functions in the language.

The first time I encountered this I was actually a bit frustrated. What was the point of calling that function on an array for example, if it doesn’t actually modify the array I called it on?! I was always forgetting this and it was the sole purpose for a whole bunch of bugs in my programs. To be honest it took me more time than it should to understand the benefits of this approach.

Declarative vs Iterative

Some of the most basic algorithms that you will be writing as a programer include looping through data and modifying it in some manner. Maybe you want to filter it or modify values.

The orthodox way that we are all taught is to use loops and mutate objects. There is nothing wrong in that, this is how most people are doing it and they will be doing it for a long time. This approach is considered imperative. By doing things this way we give the program explicit instructions of how to do the things that we need.

Functional programming on the other hand is meant to be declarative. What does this mean? You remember how the built in functions always return a new instance? This allows us to chain them with other such functions in order to do what we normally do with loops but with far less code.

The moment this clicked for me was the moment I stopped writing loops. To be honest, I can’t remember the last time I wrote a loop in JavaScript. Using this pattern helped me write shorter, cleaner and better structured code.

Of course, this is the most basic of the basic examples that you will see everywhere. No one is writing programs to multiply numbers, but the point is to understand how much work FP and Immutability can save you.

In reality you will probably be looping through a set of data, doing some conditional checks, then modifying the values and calculating something in the end. Let me show you how easier to read this can be compared to loops by giving the functions above some proper naming.

This could be done with less code if you just write the logic inside the filter, map and reduce functions but to show how verbose it can be I have abstracted the logic into functions. Due to the fact that those functions always return a new object, they can be chained one after another to produce such powerful results.

Every time you write a loop think if you will understand what you have written after an year. Now look at this code — no matter when you look at it it’s pretty clear what it does and in what order it does it.

Something more practical?

if you are still not convinced of how empowering immutability can be let’s turn our eyes to React. More specifically it’s integration with Redux. If you’re not familiar with Redux you might want to do some reading on that first.

The single source of truth in Redux applications is the store. This is an object which contains the current state of your application and your components will draw information from it. But you app’s state changes all the time. Users take actions on your page which require you to constantly modify your UI.

The Redux mantra, however, is to never mutate the state! Instead in your reducers you should always be returning a new object to take the place of the previous state.

In this example we add a list of weather data to the application state, so they can be listed by our components. Notice that the reducer is not just setting a property on the state, but instead returning an entirely new object. The previous state is unfolded using the ... operator and the new properties are added afterwards. This way they will overwrite the ones from the current state object.

In order to show different this in different situations, have a look at removing an item from the state. This reducer uses the omit function from lodash to remove an item from the state and return an entirely new object.

Your first thought may be that this is slow and constantly creating and changing objects could throttle your app. It won’t — take my word for it. Some really smart guys have worked a lot in order to ensure that this doesn’t happen.

This however enables one of the most powerful features in Redux development — time travel debugging. Because at every single time, your app’s state can be resembled as an object with certain properties if we swap it with another object that adheres to the same interface we could completely modify our app’s UI.

Time travel debugging allows you to keep track of all the previous states of your app and quickly change your UI with a single click — it just swaps the objects.

Gotchas

With the introduction of ES6 we got the const keyword. With it we can create variables which cannot be reassigned a different value. In fact if you instantiate a variable using const and then try to give it a different value you will receive an error.

But it wouldn’t be JavaScript if there wasn’t something odd with this would it? Even if you can’t change the value entirely you can still mutate it.

This is something to keep in mind when dealing with arrays. You can’t directly modify the contents of the variable but you can manipulate it’s contents like this. To avoid unnecessary headache, get your team to settle down on a variable convention and stick to it.

Thank you if you’ve read so far. Hold the clap button if you found something interesting in this article!

Up Next

Next we will be going into function composition and explaining some of the more complicated functional programming concepts such as currying and partial application. Stay tuned!

More by Alexander Kondov

Topics of interest

More Related Stories