Explained: Imperative vs Declarative programming

Explained: Imperative vs Declarative programming

You most probably have heard of declarative vs imperative programming.

You might also have looked it up, and got something like this

In computer science, declarative programming is a programming paradigm that expresses the logic of a computation without describing its control flow.

If you're like me, that makes no sense. So let's get to metaphors!

Suppose you want a coffee.

The imperative way:

I'll grab a cup from the bottom left drawer, grab some milk from the fridge, heat some milk, pour the milk into the cup, grab some coffee powder from the top shelf and pour it into the coffee, and then pick a spoon from the table and mix the coffee.

The declarative way:

Mom, I want a coffee!

Now, you want to book a cab to the office. You could either tell the driver all the exact turns and roads to take to reach the office, or you could just give them the address.

See? The imperative way is about laying out the exact steps of how to do something, while the declarative way is about just saying what we want to do.

Note: declarative programs are just an abstraction over imperative. In the end, someone needs to do the imperative work. Mom needs to make a coffee the imperative way. The cab driver needs to know the way to your office.


Alright, let's make the jump from the metaphorical world to our code and try declarative code ourselves. Here's a quick test: write a function that sums all the even numbers in an array




Time's up! I've seen many people write the answer like this:

function evenSum(numbers) {
    let result = 0;

    for (let i = 0; i < numbers.length; i++) {
        let number = numbers[i]
        if (number % 2 === 0) {
            result += number;
        }
    }

    return result;
}

This is imperative; this is laying out every single step.

Here's a more declarative solution:

const evenSum = numbers => numbers
    .filter(i => i % 2 === 0)
    .reduce((a, b) => a + b)

Here we are asking JavaScript to do what we want: filter out even numbers, then add them. We could make our function even more declarative by using a few more functions.

const isEven = n => n % 2 === 0;
const sum = (a, b) => a + b;
const evenSum = numbers => numbers.filter(isEven).reduce(sum);

Note: You must have noticed by now that functional programming is a subset of declarative programming!

You must have started seeing the benefits already. If not, here's a list:

  1. Declarative programs are way more readable. I only see "filter by even and reduce by sum", not some kind of loop which I need to manually step through to make sense of.
  2. Declarative programs are reusable. In the final code we have 3 seperate functions which we can reuse throught the codebase. Since imperative code heavily depends on state it may be hard for it to be reusable.
  3. Declarative programs are concise.