Imperative code is more readable

December 11th 2023 on Dušan's blog

And I'm tired of pretending it's not

Whenever I read about declarative code the authors invariably let it slip, almost as a fact of life, that declarative code is just inherently more readable than its imperative equivalent. But is it? All of this seems to me like some mantra most developers cite verbatim without actually reflecting on the matter.

First off, let's define our terms so everyone is on the same page while reading.

Said another way, declarative programming is a way of writing code without specifying its control flow, but rather, describing the problem to be solved using features built into the language.

To make sense of this predicament, let's take a look at an example of both. We'll implement a simple algorithm that gives us the sum of all positive and unique integers in a list. The solution is written in JavaScript, but it can be applied to any language that can be written in a declarative style.

Imperative

let sum = 0;
const seen = {};
const list = [1, -4, 5, 6, -23, 6, -47];

for (const element of list) {
    if (element > 0 && seen[element] === undefined) {
        sum += element;
        seen[element] = element;
    }
}

console.log(sum);

// output: 12

Declarative

const list = [1, -4, 5, 6, -23, 6, -47];
const sum = Array
    .from(new Set(list))
    .filter(element => element > 0)
    .reduce((accumulator, current) => accumulator + current, 0);

console.log(sum);

// output: 12

Let's take a note of the obvious things that the imperative version tells you that the declarative one doesn't, just by reading the code.

Now let's take a note at what the declarative solution implies but, critically, doesn't tell you.

I'm aware that the third point is essentially mute for languages that have support for iterators, not for JavaScript though.

Now, if you've never seen declarative code, chances are you're scratching your head at just what exactly it is that these methods do. This is the crux of my argument. Imperative code tells you everything that might be of interest to you, just by reading the code. Crucially, a new developer will be able to follow it step-by-step and understand what's going on if they're familiar with basic control flow structures like for and if. The declarative version, while shorter, doesn't tell you any of those things. Which is why it's declarative in the first place.

To quickly go over these methods without boring anyone to death:

You can learn the specifics of each one on MDN.

Don't get me wrong, declarative code has its place. I'd much rather use a declarative syntax, like HTML, when writing user interfaces than deal with whatever the hell imperative GTK code is trying to accomplish.

Declarative code is also more expressive if you already know what it does under the hood. I use .map, .filter and .reduce all the time, but I only know what they do because I've taken the time to write them imperatively. This is a common roadblock I see many people stumble upon when learning declarative programming for the first time. If that's the case for you, understanding and implementing declarative code imperatively might be something worth looking into to get a better grasp of the concept.

If you're going to write declarative code, do some research into how your language implements declarative structures so that you always know what's going on under the hood. In the case of JavaScript specifically, declarative code is inherently less performant than its imperative equivalent for some of the reasons I've stated here. Which is why I tend to avoid chaining multiple higher order functions together if I can express the same operation using a single for loop.

Conclusion

Finally, in hopes of adding some nuance to the discussion, I propose we don't just regurgitate the statements we see others making on the internet, but take the time to understand the concepts for ourselves. I can't tell you what to do, but I can tell you that being properly informed on the topic will work wonders improving your decision making skills and will make you a better developer in the long run.