loading...

Imperative vs Declarative Programming

ben profile image Ben Halpern ・1 min read

Software vs Software (10 Part Series)

1) React vs Vue: Compare and Contrast 2) AWS vs Azure vs Google Cloud 3 ... 8 3) VSCode vs Vim 4) PostgreSQL vs MongoDB 5) OOP vs Functional Programming 6) Computer Science vs Software Engineering 7) Python vs Java 8) Classical CSS vs CSS in JavaScript 9) Ruby vs Elixir 10) Imperative vs Declarative Programming

Let's compare and contrast what these concepts mean and where the approaches are most applicable.

Discussion

markdown guide
 

Imperative and declarative programming are similar to the imperative and declarative moods in English writing. The imperative mood is basically for issuing commands like "sit down" or "be quiet". The declarative mood indicates what is occurring, without strictly defining the steps to make that action occur ("John is walking to the store" rather than "left foot, right foot, left foot, ...").

Imperative programming tends to be low-level, specifying exactly what should be done, step-by-step. Declarative programming tends to be higher-level, specifying the outcome without necessarily dictating how that outcome should be achieved.

An example imperative snippet:

int temp = 0;
for (int ii = 0; ii < array.length; ++ii) {
  temp += array[ii] * array[ii]
}
cout << temp << endl;

An example declarative snippet:

println(array.map(x => x*x).sum)
 
 

A while ago I wrote about what is declarative programming

Person.walk() is declarative
walk(Person) {
// code to move the person in your ui toolkit
} is imperative

 

This is the kind of example I always use to illustrate the differences.

In the end, code is imperative and low-level. The advantage of higher level languages is that we can hide and encapsulate such low-level details behind abstractions and name these according to what they do (declarative).

 

Yeah the difference between imperative and declarative is where the low level details are.

 

Places where declarative programming has been really useful, are places where we are not particularly interested in how the output gets created, as long as it's correct. Things like web programming, SQL, and spreadsheets are obvious areas where this already works well. I think the model for it makes sense in these situations because the engines that actually generate the running programs (browser, RDBMS, Excel) have a well defined output so you can build that engine in the first place and know the results are correct.

At some level you need imperative programming because computers operate on simple instructions. Declarative programming is just another abstraction over this which is closer to a spoken language because that's usually how humans think about things anyways.

 

Imperative programming is definitely a good way to begin as it provides a conceptual model that is very easy to understand. Many of the OOP languages like C++ and Java are designed on the basis of imperative programming.

I have worked on BackboneJS which primarily supports imperative programming. The lack of two way binding due to which one had to specify the templates, models, and event listeners every time leads to loss of productivity and manageability.
On the other hand, the new javascript frameworks like React, Vue, and Angular are based on a declarative approach. In these frameworks, we are mainly dealing with the main component and the framework is responsible for performing all the Javascript/ DOM operations to get the desired result.

When working on large scale applications we often prefer the declarative programming approach as it provides the following:

  • Increased readability and maintainability
  • Easier reiterative development
  • Easier testing and debugging
 

I believe that "declarative programming" term does not help with understanding what it actually does.

Imperative is pretty straightforward. "Here's a set of steps, like a cake recipe. Follow it, and you will get a result."

Declarative? "I want a cake - figure it out"? BS.
It is actually "Data flow and transformation" programming. You pour data through a set of defined pipes and valves and some new data comes out. We just need to come up with a new, one-word, sexy term for it.

 

Ha, that is true. The declarative term somewhat misleading. In reality, it's a scale. From very imperative, where every instruction is explicit, to not as imperative. Only when you get to the other end of the scale (not imperative at all) is it truly "declarative"... but that's (in theory) impossible. Nothing can know merely from "I want a cake" exactly what to do, some assumptions and some steps must be given.

 

I usually prefer a declarative style. Imperative style makes the code hard to understand and work with later on. Here is a direct comparison. Both implementations do exactly the same.

Imperative:

function getUserDetails(user) {
  const result = {};
  result.name = "";
  if (user && user.details && user.details.firstName) {
    result.name += user.details.firstName;
  }
  if (user && user.details && user.details.lasName) {
    result.name += " " + user.details.lastName;
  }
  if (
    user &&
    user.details &&
    user.details.contact &&
    user.details.contact.email
  ) {
    result.email = user.details.contact.email;
  } else {
    result.email = "";
  }
  result.name = result.name.replace(/^\s/, "");
  return result;
}

Declarative:

const getUserDetails = (user) => ({
  name: [user?.details?.firstName, user?.details?.lastName]
    .filter(Boolean)
    .join(" "),
  email: user?.details?.contact?.email ?? "",
});

Maybe this comparison is a little bit unfair. But it shows the fact, that you get easily lost in details and spaghetti code, when writing an imperative style.

 

Imperative thinking is about order.
Declarative thinking is about dependencies.

You can code in either style with the other mindset, too.

Imperative thinking is about specialized control.
Declarative thinking is about generalized analysis.

 

The old me thought very much in the binary on/off terms of declarative / imperative. I used to think it made sense to only use one or the other. Over time I've come to realise that each flavour has it's own place. I generally think now more in terms of "how expressive my logic is". Sometimes higher-level code is better written imperatively to showcase steps, sometimes lower level things are better in declarative.

 

It depends of what you are doing. When i do stats and data science with R or even python. Even thought you aren’t writing any class perse. But you still using python classes from data science oriented library.

For me, i am using both. You are basically looking for a specific function or method to proceed a calculation or operation with a given set of data.

β€˜β€™β€™R

procedural and declarative

df is are data frame

Df = data.frame(...)
Reg <- lm(formula= y~ ., data=df)
Summary(reg)
β€˜β€™β€™

You will find cases where you want to do a functional approach to minimize error. In order to stay DRY.

This is my take so far based on my journey doing stats and learning data science.

 

Imperative to optimize for performance. Declarative to optimize for human understanding.

 

Yep, the craft lies in hiding the imperative code behind declarative means in order to make code complexity manageable.