Declarative vs. Imperative

To understand declarative vs. imperative code, I think it’d be helpful to first think about the real world.

Imagine some CEO, or some army general. They might say to their inferiors, “I need you to get X, Y and Z done”. The inferior might say, “Ok, but how do you want me to do X?”. To which the superior would probably say, “I don’t know, and I don’t care — JUST GET IT DONE.”

If you think about it, this superior isn’t really being an asshole. He’s playing the role of a higher level architect. It’d be too much for his brain to handle if he had to think about the details of how everything is going to get done. It’s enough for him to pick out what he needs done and when/where they get done.

So now let’s think about how code could be declarative/imperative.

getSize(a, b, c);

You’re saying:

“I need the size. Get it for me. Here are the 3 inputs. I don’t know or care how you get it, just get it for me so I could use it.”

That’s declarative. It would be imperative if you took the inputs and computed the size for yourself.

Now let’s think about HTML. HTML is so declarative that most people don’t even consider it to be code! Let’s look at an example:

<p>Hello</p>
<ol>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ol>
<a href='http://google.com'>Google</a>

You’re saying:

  • Display a paragraph that says “Hello”.
  • Display a numbered list that says, “One, Two, Three”. Indent the text. And space it appropriately.
  • Display the text “Google”, make it blue, make it so that it gets underlined if someone hovers over it, make it so that it changes to a different color when you click and hold (but don’t release), make it take you to google.com when clicked, make it so that it appears purple when you have clicked it already.

Again, you’re not saying how to do it. You’re not saying what the font size should be, what the spacing is, where on the page it should appear etc. You’re just saying “do it for me”. Under the hood, the browser — which is actually just a piece of software — is “doing it for you”. It parses the HTML and ultimately turns the right pixels on and off for you.

Contrast this with making a GUI in Java. When doing so, you need to write a ton of code that creates all your components, sets their location, their size, their relationships etc. (This explanation wasn’t very good, but the point is that you have to do a lot of “stuff” that gets done automatically for you when you use a declarative language like HTML.)

Angular tries to be very declarative.

Consider data binding:

<input ng-model='user.name'>
<p>Hello {{user.name}}</p>

In essence, what you’re saying is, “just make it so that whatever is typed in the input box shows up inside those curly braces”. This is a pretty declarative instruction. A more imperative way to perform that instruction would involve:

  1. Listening for changes to the input field.
  2. Getting the text from that DOM node.
  3. Updating your model.
  4. Finding the paragraph’s DOM node.
  5. Updating the text of the paragraph’s DOM node.

See the difference?

Consider directives:

Under the hood, these directives are just code for certain HTML and JavaScript. It’s like this: “when you see this directive, substitute it for this HTML and this JavaScript”.

One important way that directives could be used is to DRY out your HTML. If you have a certain component that gets used multiple times, you could create a directive for it in the same way that you’d create a function for a block of code you’ll run multiple times. And to continue that analogy, directives could take arguments (via HTML attributes) and respond accordingly just like functions could take arguments and respond accordingly.

Consider dependency injection:

In Angular, you could do something like this:

app.controller('MainController', function(User) {
// can access User here
});

If you think about it, that’s pretty crazy! You declared a function that has a User parameter. Ok. But who’s calling that function, and how are they passing in the User that you want? What if User depends on something else? How will it know what User depends on and how to meet those dependencies?

When you use Angular, you don’t have to think about any of that! Angular lets you make declarative statements like the one above, and it figures the rest out for you. All you have to say is, “give me the User service”, and it’ll get it for you.

To me, the idea of declarative vs. imperative seems to be pretty much the same thing as the idea of abstraction. Something high-level that has the implementation details abstracted away from you is declarative. Something lower-level that forces you to implement the details yourself is imperative.

And so, things aren’t “declarative” or “imperative” in and of themselves. They’re declarative/imperative relative to other things. There might be a spectrum:

A > B > C > D > E

C might be more declarative than D, but less declarative than B. So… is C declarative or imperative? I don’t think that there’s an answer to that question because I think that it’s only possible to be declarative/imperative relative to something else.

To put it in terms that you programmers might understand: the question takes two arguments (is X declarative relative to Y?) and if you try to call it with one argument (is X declarative?), you’ll get a compile error.

isDeclarative(X, Y); // success
isDeclarative(X); // compile error

--

--

Rationality, effective altruism, startups, learning, writing, basketball, Curb Your Enthusiasm

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Adam Zerner

Rationality, effective altruism, startups, learning, writing, basketball, Curb Your Enthusiasm