159

Recently I've been studying a lot about the functionality and the ways to use the Facebook JavaScript library React.js. When speaking of its differences to the rest of the JavaScript world often the two programming styles declarative and imperative are mentioned.

What's the difference between both?

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Socrates
  • 8,724
  • 25
  • 66
  • 113
  • 35
    http://latentflip.com/imperative-vs-declarative/ `Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen. Declarative programming: telling the "machine"1 what you would like to happen, and let the computer figure out how to do it.` – rickyduck Nov 11 '15 at 17:31
  • 5
    Tyler McGinnis wrote [a long article](https://tylermcginnis.com/imperative-vs-declarative-programming/) on this with some good examples. – Ian Dunn Aug 12 '17 at 10:08
  • 1
    Why add long answer in as a comment?.. – Alex Apr 23 '19 at 16:55
  • 2
    The above link is correct, but a trailing slash included in the link causes 404. [latentflip.com/imperative-vs-declarative](http://latentflip.com/imperative-vs-declarative) – James Yoo Jul 09 '20 at 18:58

11 Answers11

234

A declarative style, like what react has, allows you to control flow and state in your application by saying "It should look like this". An imperative style turns that around and allows you to control your application by saying "This is what you should do".

The benefit of declarative is that you don't get bogged down in the implementation details of representing the state. You're delegating the organizational component of keeping your application views consistent so you just have to worry about state.

Imagine you have a butler, who is kind of a metaphor for a framework. And you would like to make dinner. In an imperative world, you would tell them step by step how to make dinner. You have to provide these instructions:

Go to the kitchen
Open fridge
Remove chicken from fridge
...
Bring food to the table

In a declarative world, you would simply describe what you want

I want dinner with chicken.

If your butler doesn't know how to make chicken, then you cannot operate in a declarative style. Just like if Backbone doesn't know how to mutate itself to do a certain task, you can't just tell it to do that task. React is able to be declarative because it "knows how to make chicken", for example. Compared to Backbone, which only knows how to interface with the kitchen.

Being able to describe the state reduces the surface area for bugs dramatically, which is a benefit. On the other hand, you might have less flexibility in how things occur because you're delegating or abstracting away how you implement the state.

Nathan Hagen
  • 12,440
  • 4
  • 26
  • 31
122

Imagine a simple UI component, such as a "Like" button. When you tap it, it turns blue if it was previously grey, and grey if it was previously blue.

The imperative way of doing this would be:

if( user.likes() ) {
        if( hasBlue() ) {
            removeBlue();
            addGrey();
        } else {
            removeGrey();
            addBlue();
        }
    }

Basically, you have to check what is currently on the screen and handle all the changes necessary to redraw it with the current state, including undoing the changes from the previous state. You can imagine how complex this could be in a real-world scenario.

In contrast, the declarative approach would be:

return this.state.liked ? <blueLike /> : <greyLike />;

Because the declarative approach separates concerns, this part of it only needs to handle how the UI should look in a sepecific state, and is therefore much simpler to understand.

SeyyedKhandon
  • 5,197
  • 8
  • 37
  • 68
Ahmed Eid
  • 4,414
  • 3
  • 28
  • 34
48

It is best to compare React (declarative) and JQuery (imperative) to show you the differences.

In React, you only need to describe the final state of your UI in the render() method, without worrying about how to transition from previous UI state to the new UI state. E.g.,

render() {
  const { price, volume } = this.state;
  const totalPrice = price * volume;

  return (
    <div>
      <Label value={price} className={price > 100 ? 'expensive' : 'cheap'} ... />
      <Label value={volume} className={volume > 1000 ? 'high' : 'low'} ... />
      <Label value={totalPrice} ... />
      ...
    </div>
  )
}

On the other hand, JQuery requires you to transition your UI state imperatively, e.g, selecting the label elements and update their text and CSS:

updatePrice(price) {
  $("#price-label").val(price);
  $("#price-label").toggleClass('expansive', price > 100);
  $("#price-label").toggleClass('cheap', price < 100);

  // also remember to update UI depending on price 
  updateTotalPrice();
  ... 
}

updateVolume(volume) {
  $("#volume-label").val(volume);
  $("#volume-label").toggleClass('high', volume > 1000);
  $("#volume-label").toggleClass('low', volume < 1000);
  
  // also remember to update UI depending on volume
  updateTotalPrice();
  ... 
}

updateTotalPrice() {
  const totalPrice = price * volume;
  $("#total-price-label").val(totalPrice);
  ...
}

In the real world scenario, there will be many more UI elements to be updated, plus their attributes (e.g., CSS styles, and event listeners), etc. If you do this imperatively using JQuery, it will become complex and tedious; it is easy to forget to update some parts of the UI, or forget to remove old event handlers (cause memory leak or handler fires multiple times), etc. This is where bugs happen, i.e., UI state and the model state are out of sync.

States out of sync will never happen to React's declarative approach, because we only need to update the model state, and React is responsible to keep the UI and model states in sync.

  • Under the hook, React will updates all changed DOM elements using imperative code.

You may also read my answer for What is the difference between declarative and imperative paradigm in programming?.

PS: from above jQuery example, you may think what if we put all the DOM manipulations in a updateAll() method, and call it every time when any of our model state changes, and the UI will never be out of sync. You are correct, and this is effectively what React does, the only difference is that jQuery updateAll() will cause many unnecessary DOM manipulations, but React will only update changed DOM elements using its Virtual DOM Diffing Algorithm.

engineforce
  • 2,840
  • 1
  • 23
  • 17
33

This is great analogy:

*An imperative response: Go out of the north exit of the parking lot and take a left. Get on I-15 south until you get to the Bangerter Highway exit. Take a right off the exit like you’re going to Ikea. Go straight and take a right at the first light. Continue through the next light then take your next left. My house is #298.

A declarative response: My address is 298 West Immutable Alley, Draper Utah 84020*

Source: https://tylermcginnis.com/imperative-vs-declarative-programming/

miken32
  • 42,008
  • 16
  • 111
  • 154
serkan
  • 6,885
  • 4
  • 41
  • 49
15

Imperative code instructs JavaScript on how it should perform each step. With declarative code, we tell JavaScript what we want to be done, and let JavaScript take care of performing the steps.

React is declarative because we write the code that we want and React is in charge of taking our declared code and performing all of the JavaScript/DOM steps to get us to our desired result.

Pang
  • 9,564
  • 146
  • 81
  • 122
Nikhil
  • 1,267
  • 15
  • 16
7

Declarative programming is a style of programming where applications are structured in a way that prioritizes describing what should happen over defining how it should happen.

In order to understand declarative programming, Let's compare it with imperative programming (style of programming that’s only concerned with how to achieve results with code).

Example: making a string URL-friendly. Typically, this can be accomplished by replacing all of the spaces in a string with hyphens, since spaces are not URL-friendly. First, An imperative approach to this task:

const string = "difference between declarative and imperative in react.js";
const urlFriendly = "";
for (var i = 0; i < string.length; i++) {
    if (string[i] === " ") {
      urlFriendly += "-";
    } else {
      urlFriendly += string[i];
    }
}
console.log(urlFriendly); // "difference-between-declarative-and-imperative-in-react-js"

In this example, we loop through every character in the string, replacing spaces as they occur. The structure of this program is only concerned with how such a task can be achieved. We use a for loop and an if statement and set values with an equality operator. Just looking at the code alone does not tell us much as imperative programs require lots of comments in order to understand what’s going on.

Now let’s look at a declarative approach to the same problem:

const string = "Difference between declarative and imperative in React.js?";
const urlFriendly = string.replace(/ /g, "-");
console.log(urlFriendly);

Here we are using string.replace along with a regular expression to replace all instances of spaces with hyphens. Using string.replace is a way of describing what’s supposed to happen: spaces in the string should be replaced. The details of how spaces are dealt with are abstracted away inside the replace function.

In a declarative program, the syntax itself describes what should happen, and the details of how things happen are abstracted away.

Essentially, declarative programming produces applications that are easier to reason about, and when it’s easier to reason about an application, that application is easier to scale. Additional details about the declarative programming paradigm can be found at the Declarative Programming wiki.

Now, let’s consider the task of building a document object model. An imperative approach would be concerned with how the DOM is constructed:

const target = document.getElementById("target");
const wrapper = document.createElement("div");
const headline = document.createElement("h1");
wrapper.id = "welcome";
headline.innerText = "Hello World";
wrapper.appendChild(headline);
target.appendChild(wrapper);

This code is concerned with creating elements, setting elements, and adding them to the document. It would be very hard to make changes, add features, or scale 10,000 lines of code where the DOM is constructed imperatively.

Now let’s take a look at how we can construct a DOM declaratively using a React component:

const { render } = ReactDOM;
const Welcome = () => (
   <div id="welcome">
      <h1>Hello World</h1>
   </div>
);

render(<Welcome />, document.getElementById("target"));

React is declarative. Here, the Welcome component describes the DOM that should be rendered. The render function uses the instructions declared in the component to build the DOM, abstracting away the details of how the DOM is to be rendered. We can clearly see that we want to render our Welcome component into the element with the ID of target

Source: Modern Patterns for Developing React Apps

Neri Barakat
  • 1,555
  • 20
  • 25
1

Declarative vs Imperative

Declarative Programming is like asking your friend to paint your House. You don’t care how they clean it,what colour they use to paint,How many resources they used to complete it`.

//Declarative For Searching element from an array
  array.find(item)

The opposite of declarative is imperative. A common example of an imperative approach is is you told your friend exactly what to do to paint your House.

  • Wash the house with detergent.
  • Use Narolac paint or asian paint
  • Paint the roof with Green color.
  • Get 3 members to contract,etc.

//Imperative Algo

def imperative_search(array, item)
  for i in array do
    if i == item
      return item
    end
  end
  return false
end
Debendra Dash
  • 5,334
  • 46
  • 38
1

Explaining every bit of steps is an Imperative approach e.g. We have to create a paragraph tag with Hello World! text inside.

//Imperative 

const para = document.createElement('p');
para.innerText = 'Hello World !';
document.querySelector('#root').appendChild(para);

Defining desired end target state without specifying exact procedure. i.e p tag with text, without telling to createElement or innerText

 //Declarative 

 import React from "react"; 
 import ReactDOM from "react-dom"; 
 
 const App = () =>{
  return(<p>Hello World !</p>);
 }

 ReactDOM.render(<App />, document.getElementById("root"));
Kim Desrosiers
  • 744
  • 7
  • 13
0

I'll start with an analogy: I have two cars, in my two cars I want the temperatue inside my car to be normal room temperature ~ 72°F. In the first (older) car, there's two knobs to control the temperature (1 knob to control the temperature and 1 knob to control the airflow). When it gets too hot, I have to adjust the first knob to lower the temperature and maybe change the airflow) and vice verse if it's too cold. This is imperative work! I have to manage the knobs myself. In my second (newer) car, I can set/declare the temperature. Which means I don't have to fiddle with the knobs to adjust the temperature my car knows I declare/set it to 72°F and my car will do the imperative work to get to that state.

React is the same, you declare the markup/template and stat then React does the imperative work to keep the DOM in sync with your app.

<button onClick={activateTeleporter}>Activate Teleporter</button>

Instead of using .addEventListener() to set up event handling, we declare what we want. When the button is clicked, it'll run the activateTeleporter function.

nullify0844
  • 4,641
  • 1
  • 22
  • 16
0

This is my understanding so far:

Declarative code (almost?) always is a layer of abstraction above code that is more imperative in nature.

React allows you to write declarative code that is a layer of abstraction above the imperative code that interacts with the DOM directly (eg. the diffing algorithm). If you need to write imperative code (ie. interact with the DOM directly) React provides Refs as an escape hatch.

David
  • 4,191
  • 2
  • 31
  • 40
0

So, what is the declarative programming?

Declarative programming is when a more qualified specialist writing code in a way when its behavior can be changed by using external config which represent oriented graph of objects. For example, Jetpack Compose or Flutter Widgets.

avalonia funcui

Legacy solutions had used an xml-like markup languages which represented ui object tree. For example, XAML in WPF (see FuncUI) or *.ui in Qt. They still have internal object composition syntax (like DOM API) but it is highly recomended to use markup language to implement the UI in a declarative way.

wpf-xaml

After Facebook introduced JSX the whole enterprise migrated to web because it gives to developer more accessibility to design features and customize user experience by using functional programming (code significantly cheaper). In that case, JSX is declarative to HTML (more correct DOM API -> React -> JSX)

facebook-jsx

If you studied computer science you must know that everything in software is built on top of abstractions. For example in macOS hardware is used by mach kernel. Mach kernel is used by Core OS. Core OS is used by QuckTime. QuickTime is used by GUI. As you can see, the subject of the relation is declarative to the object of the relationship

osx-architecture

The idea is simple. If C/C++ language is declarative to assembly, JavaScript is declarative to C++, React is declarative to JavaScript then usually developers are designing something which will reduce cost of app development when using React (React -> Plain JS objects -> JSX)

react-declarative

The community has come up with a new term to define this phenomenon, It called low code. You can check the source code of that sample app in this codesanbox or browse the github organisation for more samples

import { Scaffold2, IScaffold2Group } from "react-declarative";

const options: IScaffold2Group[] = [
  {
    id: 'build',
    label: 'Build',
    children: [
      {
        id: 'authentication',
        label: 'Authentication',
        isVisible: async () => await ioc.authService.hasRole('unauthorized'),
        icon: PeopleIcon,
        tabs: [
          { id: 'tab1', label: 'Tab1 in header', },
          { id: 'tab2', label: 'Tab2 in header', },
        ],
        options: [
          { id: 'tab1', label: 'Tab1 in side menu' },
          { id: 'tab2', label: 'Tab2 in side menu' },
        ],
      },
      { id: 'Database', label: 'Label is optional (can be generated automatically from ID in snake case)', icon: DnsRoundedIcon, },
      { id: 'Storage', isDisabled: async () => await myAmazingGuard(), icon: PermMediaOutlinedIcon, },
      { id: 'Hosting', icon: PublicIcon, },

...

<Scaffold2
  options={options}
  ...

P.S. Also the declarative programming is more SOLID way because we are not making GUI classes instances through new operator manually (see Dependency inversion principle)

Petr Tripolsky
  • 1,419
  • 15
  • 23