DEV Community

Cover image for Declarative. Imperative. Intentional.
Drew Marshall
Drew Marshall

Posted on

Declarative. Imperative. Intentional.

As developers, we spend a lot of time talking about programming paradigms.

Imperative programming.

Declarative programming.

Functional programming.

Object-oriented programming.

Event-driven programming.

Over the years, we've developed countless ways to describe how software should be written.

But recently I've been wondering if we're missing something.

What if there is another layer above all of them?

What if the future isn't just declarative or imperative?

What if it's intentional?

Imperative Languages

Most developers begin with imperative programming.

Imperative code tells the computer exactly what to do.

Step by step.

Instruction by instruction.

For example:

const users = database.getUsers();
const activeUsers = users.filter(user => user.active);
activeUsers.sort(sortByName);
render(activeUsers);
Enter fullscreen mode Exit fullscreen mode

The focus is on the process.

The developer describes the sequence.

Do this.

Then this.

Then this.

The computer follows the instructions.

Imperative programming is powerful because it gives precise control.

But it also means the developer carries the burden of describing every step.

Declarative Languages

Declarative programming moved the conversation forward.

Instead of describing how something should happen, you describe what should happen.

SQL is a great example.

SELECT * FROM users WHERE active = true;
Enter fullscreen mode Exit fullscreen mode

You aren't describing indexes.

You aren't describing loops.

You aren't describing memory allocation.

You simply describe the result you want.

The database engine determines how to achieve it.

React, HTML, CSS, infrastructure tools, and many modern frameworks have embraced this idea.

Describe the outcome.

Let the system determine the implementation.

That abstraction has made software significantly more productive.

But I don't think it is the final step.

The Problem With Declarative Systems

Even declarative systems often require us to think in implementation details.

Consider responsive design.

Many solutions look something like this:

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
Enter fullscreen mode Exit fullscreen mode

This is certainly more declarative than writing raw CSS.

But we're still describing implementation.

We're still talking about columns.

We're still talking about breakpoints.

We're still talking about layout mechanics.

The system knows what we're doing.

But it doesn't necessarily know why we're doing it.

Intentional Design

This is where I think things get interesting.

Imagine instead:

<div adapt="grid">
Enter fullscreen mode Exit fullscreen mode

Or:

<div adapt="grid" mobile="stack" tablet="2x1">
Enter fullscreen mode Exit fullscreen mode

Now we're no longer describing CSS.

We're describing intent.

The element is communicating its desired behavior.

It should adapt.

It should reorganize itself based on context.

The system becomes responsible for determining how that adaptation happens.

The focus shifts away from implementation and toward purpose.

Describing Goals Instead Of Mechanisms

The more I think about it, the more I realize many of the systems I enjoy building move in this direction.

Take SQL.

You describe the data you want.

Take infrastructure-as-code.

You describe the infrastructure you want.

Take Nectarine.

You describe schemas, APIs, and resources.

The system generates the implementation.

Now consider layout.

What if we described the experience we want instead of the CSS we want?

What if we described content behavior instead of breakpoints?

What if we described goals instead of mechanisms?

That's not simply declarative.

That's intentional.

The Library Starts Developing A Language

One of the fascinating things about building software libraries is that eventually they develop their own language.

Not a programming language.

A design language.

A way of expressing ideas.

A vocabulary.

A philosophy.

The best libraries don't just provide features.

They teach developers how to think.

Every API decision contributes to that language.

Every naming convention contributes to that language.

Every abstraction contributes to that language.

Over time, the library begins expressing values.

Not just functionality.

Intent Over Implementation

The more systems I build, the less interested I become in implementation details leaking into every layer.

Implementation matters.

Sometimes it matters a lot.

But most developers aren't trying to express implementation.

They're trying to express intent.

They know what they want the system to accomplish.

The challenge is communicating that intent clearly.

Good abstractions reduce implementation complexity.

Great abstractions make intent obvious.

Looking Forward

I don't think imperative programming is going away.

I don't think declarative programming is going away.

Both remain incredibly useful.

But I do think software is slowly moving toward systems that understand intent.

Systems that allow us to describe goals.

Systems that translate purpose into implementation.

Systems that focus less on mechanics and more on outcomes.

Maybe that isn't a new programming paradigm.

Maybe it's simply a design philosophy.

Either way, it's a direction I find myself increasingly drawn toward.

Not because it hides complexity.

But because it lets developers focus on what they actually mean.

And sometimes meaning is more important than mechanics.

Top comments (0)