Imperative programming vs declarative
Published: 2023-10-02 10:01:07


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6dmd2avecslcprno2x65.png)
I’ve recently read an [article](https://dev.to/ruizb/declarative-vs-imperative-4a7l) and a [yt video](https://www.youtube.com/watch?v=E7Fbf7R3x6I) on this subject.
Comparisions and explanations usually were pretty good I got to give them that but…

Here are my thoughts:

Usually, people having such dilemmas (imperative vs. declarative) are in favor of declarative programming, or if they have no opinion, they will most likely stumble upon articles praising declarative programming.

But the truth is that neither of those paradigms is better or worse; both are useful, and the power lies in using both.

There is also an ugly side to too much declarative programming. (I’m saying this to balance out the praise for declarative programming.)

For example, web routing systems are usually done declaratively, and this seems to be a good approach because there are not many combinations -> some URLs with none, 1 or few “parameter/:segments” and methods from the list: GET, POST, and so on.

On the other hand, you have Spring Boot (Java) or Symfony (PHP) trying to do everything declaratively in annotations, and you can spend weeks reading documentation about JSR-303 validation, and you will still run into more complicated cases where you will have no clue how to cover them.
And even if you do it correct it will be confusing to follow and weird to test.

And doing it imperatively will have a constant (usually pretty rapid) time for design, and once it is finished, you will never have any problems with it, and you will have maximal flexibility — obviously if you know what you are doing.

Yet you will have to deal with people being disgusted with the fact you’ve done validation imperatively because “That’s not how you should code in Spring Boot.” But on the other hand, they will never be willing to answer questions on how to do a particular more complex case because probably they have never covered moderately complicated case or they were just doing it carelessly. Allowing for a 500 status code when a field is missing or something. And they called this error handling.

It is worth remembering, though, that too many declarative layers will be limiting -> You will have an extra case that will not be predicted on the design layer, and the entire abstraction goes out the window.

**Just learn to recognise when it is worth introducing a declarative approach and even more when you should not do that.**

Another example:

Programmers often fall into the trap of building a tool **targeted for developers**, and they have a brilliant idea of building a declarative layer of control — some json/yaml file with list of options ON/OFF style.

You will end up with a bunch of options to choose from, and if you have a case to cover beyond available options, then “Naha — you don’t”

(I know I’m speaking in general terms, but I can’t speak specifically about the library I have in mind because it would be inappropriate to do so here. Talking about JSR-303 is fine, this is big tool with lots of maintainers … and who cares about my opinion in the end there)

Where if that tool is designed for developers, then it would be reasonable to just expose some function as a config (with default implementation out of the box) with some internal tools exposed in the context of that function and as developers do what you need with it. Even bring your own tools to the context and extend its basic functionality.

By doing that you provide better — actually ultimate — expressiveness to the target user. Because for programmer programming language is ultimate tool to express what he needs.

So in this case, an imperative approach will be much more powerful; as a result, the tool would be more universal. Internally it will be just simpler, which in turn always translates to better stability and a smaller footprint and easier maintainability.

But even despite all the above, there will always be someone advocating the superiority in all cases of declarative programming over imperative.

So my conclusion is:

Even despite the fact that these are ‘paradigms,’ it is better to think of both as ‘tools.’ All tools serve different purposes, and there is no ‘one’ tool for everything and programming is art of tradeoffs.