Declarative vs. Imperative Programming

Declarative vs. Imperative Programming

ยท

7 min read

If you've worked with functional programming at all, chances are you've heard the terms "declarative" and "imperative" at some point. These two terms are mental models, or programming paradigms, which is just fancy computer science jargon for saying it's a style of programming.

In this article, I will explain the differences between the declarative and imperative approaches as well as provide examples so you can draw comparisons.

Imperative Approach

Most definitions of imperative programming will tell you that it is code that describes how to achieve a certain outcome. For example, many low-level languages are imperative by nature since they need to know how to perform a list of instructions that the computer can execute.

Let's look at a non-programming example where the statement "pass me a glass of water" is a declarative phrase. If you were to imperatively ask someone to do this, it could sound something like this:

"Walk over to the table, grab the glass of water, pick it up off the table, walk about 15 feet and lastly hand me the glass."

In this contrived example, you're describing every action that the person needs to perform for you to get water. While the phrase "pass me a glass of water" is describing what the action will be. Both of these phrases will get the job done, however, one is more verbose than the other.

Declarative Approach

In contrast, declarative programming describes what to do and what should happen. As programmers, we have a natural tendency to think in a more declarative way.

Many front-end frameworks and higher-level programming languages provide an abstraction that allows programmers to write code in a declarative format. A benefit of this is that the code is easier for us to read and write.

One of the main reasons functional programming has become so popular is because it steers you in the direction of being more declarative. By composing functions and using them in conjunction with one another, we are declaratively telling the program what to do instead of how to do it.

Now let's look at some examples to drive the point home.

Imperative Example

The OG for loop is typically used to provide an imperative example. for loops are good examples of an imperative approach because you have to write out exactly how the loop should operate and increment and whatnot. You are providing a list of instructions.

Below is an imperative way to take a list of musicians and create a new array of names:

const musicians = [
{
  name: "Stan Getz",
  instrument: "Tenor Saxophone"
},
{
  name: "Dave Brubeck",
  instrument: "Piano"
},
{
  name: "Paul Desmond",
  instrument: "Alto Saxophone"
}  
];
const musicianNamesImperative = [];

for (let i = 0; i < musicians.length; i++) {
  musicianNamesImperative.push(musicians[i].name);
}
//Output: [ 'Stan Getz', 'Dave Brubeck', 'Paul Desmond' ]

Notice how we are manually describing how the code needs to create a new array of names:

  1. Create an empty array.
  2. Initialize the loop counter variable to 0.
  3. Loop through as long as the counter is less than the length of the array.
  4. Increment the loop by one each iteration.
  5. Execute the statement in between the brackets.

Next, we'll look at a declarative way to achieve the same result as the one above.

Declarative Example

Array methods like map, filter, and reduce are good examples of a declarative approach because they describe what is happening (as opposed to how) and do not mutate state in any way.

Below is a declarative way to take a list of musicians and create a new array of names.

const musicianNames = musicians.map(musician => musician.name)

Besides being less code than the imperative approach, you can see that we are declaring the output we want. We're not concerning ourselves with the inner details of looping through and assigning as well as all the other things we had to manually program in the imperative example. All we have to do is pass a callback function with what we want and it will return back a new array with the desired output.

Behind the Scenes

Declarative code will get compiled or processed by something imperative like machine code or an operating system. At the end of the day, the computer still has to know how something needs to be done. Eventually, the code has to compile into a format that does imperative things. Higher-level languages just provide a nice abstraction layer that makes it easier for humans to write code that will later be converted into something the computer can understand.

El Fin ๐Ÿ‘‹๐Ÿฝ

I hope this tutorial debunks the differences between the declarative and imperative paradigms. Adopting a declarative approach is a fundamental part of functional programming so understanding the differences between the two paradigms is a good thing to know!

If you enjoy what you read, feel free to like this article or subscribe to my newsletter, where I write about programming and productivity tips.

As always, thank you for reading, and happy coding!

Resources