<-- (back)

The declarativeness ladder

23 Mar, 2025
musings
dev
0.8k words

One way to classify programming paradigms is whether it is imperative or declarative. In an imperative setting you tell the computer how to do something, while in an imperative setting you tell it what you want to do, and it is some other process that figures out how to exactly do that.

On its face, I think it's natural to think that "wait, isn't declerative just clearly better?". Of course, none is strictly better and there is a tradeoff. Namely, imperative approaches give you more control but are harder to work with, while declarativeness makes it easier to build and compose larger level systems but makes it often harder to do some low level stuff in the exact way you might want to.

Declarativeness and imperativeness isn't only about programming, though. There are so many examples in all walks of life where there can be an imperative approach and a declarative one. For example, I could make a pizza recipe that tells you "put x grams of water, y of flour, z of yeast ... preheat at 250C ... take out after 5 minutes ... " and that is a valid recipe, but I could also say "make a wet dough, put it in the oven and cook it until the top is browend" and it is essentially the same recipe. The first is imperative, the second is declarative.

And even though a lot of things can categorized as imperative or declerative, generally you say this about programming languages as a whole. C is the archetypical imperative language. I'm not sure if there is a single obvious main representative of declarative languages, but I would probably say Haskell or most ML-style, functional languages.

But C is declarative, actually. You can just declare variables and functions and everything gets reserved in the stack and it uses the calling conventions for the platform. It even optimzes the generated assembly! And assembly is also declarative because you just put labels of stuff you want to have in memory and the assembler figures out what the addresses of each thing is going to be and it translates the instructions to the appropriate machine code. And machine code is declarative because you just say what instruction you want to run and the CPU figures out what lines to power and buses to connect.

And I could go on and on but I think the point is clear. There is no such thing as declarative or imperative in the absolute. There is only the declarativeness ladder. In the cooking example you can also be more or less declarative (either "make a pizza!" or explain the muscle movements to get it done).

So, which is better?

There is a thing that I think especially not very experienced programmers think, which is that imperative is somehow clearly better but you just have to "get good" at it and then you're listo! But that is clearly not the case because you can just keep going down the declarativeness ladder and you would be, like, flipping bits by hands. No bueno.

Then, on the other side, some experienced and not very experienced programmers alike think that declarative is somehow clearly better and you just have to "get good". Of course it depends (and of course Rust is the solution because it allows you to go up and down accordingly but it's not evangelism time rn). For the imperative case I said the argument is flawed because you could always keep going down, but what would going up in the declarativeness ladder be? Maybe the answer is using frameworks and stuff like that but, ultimetaly, I think it's... AI. What is more declarative than that? But AI is clearly not a silver bullet and actually demonstrates the challenges of providing a declarative system, and that declarativeness can only be as good as the "compiler" you use.

I would be amiss if I didn't point out that the point of "declarative is clearly better if it would work exactly as advertised" is very similar to the argument for socialism, and the counterargument to socialism is similar to the counterargument to declerativeness (that is, that in practice it doesn't work). This is a very surface-level analogy but it's funny that, without a doubt, programers that prefer declerative paradims are generally more left-leaning and the imperative ones are more right-leaning. I don't know if it goes further than that. I'm thinking that socialism is more "declarative" because you basically "declare" that the point is to maximize collective happiness, while capitalism is more "imperative" in the sense that of course you also want to maximize happiness and such but you say that the main way to do that is by having the free market and whatnot. But it's a flimsy argument, so it's no more than an anecdotal obseration.