Declarative, Imperative, and all that
For the last few years, concepts from Functional Programming have been trickling into the mainstream. Whereas earlier these alien ideas were met with shrugs and raised eyebrows, now it’s cool to be seen as one who writes monads or dishes out wisdom on paradigms and whatnot.
I was quite happy, therefore, to see that the latest edition of the React newsletter by ui.dev had an article on what it means for React to be declarative. Now, if you’ve not been living under a rock for some time, you already have encountered these terms, looked them up, and come across trivial examples of what the difference is.
Unfortunately, I found the article in question making the same mistakes. All it says (and it’s stuff that’s just a search away and will be provided as a summary by the search engine) is that telling the engine how to build the UI is imperative, while writing code that just describes the UI is declarative.
So, you can say that jQuery is imperative while React is declarative.
That’s where the article ends, and that’s where my concern lies: What did we gain out of this exercise?
We’re programmers; we’re supposed to build things and evaluate new stuff based on how it affects our work. How does this extremely shallow and artificial distinction between imperative and declarative programming help me? Do we gain anything by writing declarative code?
I mean, Golang is out and out imperative, and yet engineering and quality-control wise, it’s one of the best choices you can make for development today. Should we instead close our eyes to this reality and insist that Golang is imperative and therefore bad?
filter(), etc., are considered declarative, but if I think of the code that uses them as a whole, I can’t help feel that the whole thing is imperative – no matter what we’re doing, we’re always telling the machine what to do.
Yes, I can see how declarative programming is more human-like to read and reason about, so that alone might lead to fewer opportunities for writing bugs. But, I expected a little more (okay, a lot more) from an article getting curated by such a prestigious newsletter, and one attempting to deal with such a fine issue.
If you ask me, declarative equals abstraction. You’re not somehow doing something magical when writing declarative code – the stuff underneath is heavily imperative. Rip open the React source code and you’ll find shockingly imperative, DOM-mutative statements. It’s just that the library abstracts it all away and allows you to code in a more declarative paradigm. By itself, coding in a declarative or imperative way doesn’t equal sin or virtue automatically.
Further, if you really are interested in exploring this difference, the contrast is best studied in a single language or framework (environment). Write imperative code in C++ and then write declarative code in C++ and see how they compare. There’s not much point in comparing, say, React and jQuery because they’re optimized for different paradigms and unless you’re very skilled in both, any learning you derive about these differences will be shallow.