3

On Wikipedia, the article Programming paradigms defines

  • declarative as a paradigm in which the programmer merely declares properties of the desired result, but not how to compute it;
  • imperative as a paradigm in which the programmer instructs the machine how to change its state.

Is assignment declarative or imperative?

For instance,

  • x = 3 in Python;
  • PUT / HTTP/1.1\r\nHost: domain.org\r\n\r\n{"x": 3} in HTTP;
  • UPDATE relation SET value = 3 WHERE key = 'x'; in SQL.

5 Answers5

9

Declarative vs imperative programming cannot always be distinguished on a syntactical level. To a large part, this is more about different programming styles: a declarative program will mostly describe the structure of the problem, whereas an imperative program will describe the steps of an algorithm that solves the problem. There is an interesting aspect we must get out of the way first, though: mutability: imperative programming inherently implies that data is modified. In declarative programming, we more often have descriptions of data flows without actual mutability. But while imperative/mutable vs declarative/immutable are correlated, this is not a hard and fast rule to distinguish them.

In your x = 3 Python example, we can't tell what programming paradigm is being used, because that would depend on the wider context. Python as a whole is biased towards imperative programming. It is very statement-oriented. Every statement does something, usually by modifying some state. But an assignment x = 3 could be interpreted as a declarative statement of fact: “in this context, x = 3”, or as an imperative command: “modify the x variable to have the new value 3”.

HTTP is a protocol, and I don't think it makes sense to apply programming language categories to this protocol.

You SQL example is interesting: the UPDATE statement modifies the state of the database, but SQL is widely considered to be a declarative language. In that SQL statement, you don't describe how to update the database. You don't look up indices, you don't perform table scans, you don't acquire locks, you don't update indices. The SQL statement just expresses a problem in this notation for relational algebra. I think this illustrates nicely that you can't always clearly separate these two concepts. A sequence of SQL statements might be imperative (especially when part of a stored procedure), but individual statements are a declarative description of database operations.

amon
  • 135,795
5

In a declarative approach, you declare facts, for example that gravity g is 9.80665 m/s2 or the number or wheels x is 3.

Many programming languages express this with some kind of declaration or assignment statement:

let g = 9.80665   // swift
double x = 3;       // c++, java
spaceship(red).  % prolog

In the declarative paradigm you tell the rules and let the system apply these rules to find the result. The rules and facts can be declared in any sequence.

In the imperative paradigm, you have to tell how to use these facts to come to the result; the sequence of operations matters. You may use assignment for other purpose than defining facts: every time you use an assignment that depends on the sequence of statements, and every time you use an assignment to change the previous value of a variable, it is no longer declarative.

Conclusion: assignment can be declarative or imperative, depending on how it is used.

Christophe
  • 81,699
2

First we need to clarify the distinction between "declarative" and "imperative".

Be aware that there is no single canonical definition of "declarative" in computer science, so there is a certain level of subjective opinion and a lot of grey area. But a reasonable definition is:

In a declarative language the code is a specification of the desired end result. In an imperative language the code specifies a sequence of operations executed over time (hopefully resulting in the desired end result).

It follows from this that imperative languages have a notion of mutable state. Each operation change mutable state or have some other side effect (like generating output).

Declarative languages describes a single state and does not have any explicit notion of sequential execution or mutable state.

This brings us to assignment. Assignment can really have two meanings. In an imperative language like Python, assignment sets a mutable variable to a particular state. A variable can have multiple states over time (hence the name).

Declarative and functional languages can also have assignment, but these are more like aliasing. It binds a name to a particular value or expression in a given context. But the binding does not change over time. Assignment in declarative or functional languages are therefore more often called declarations or bindings rather then assignments.

This distinction may be subtle, but consider that in an imperative language like Python, a name like 'foo' might refer to different variables in different scopes and each variable may change value over time. In a declarative language, the same name may refer to different binding in different scopes, but a binding never change over time.

For example CSS is a declarative language and CSS variables are assigned a value, but they cannot change at runtime (which means the name "variable" is really a misnomer - it is a constant declaration rather than a variable).

Update in SQL is imperative since they change state. Base tables are sometimes called "relation variables" (or "relvars") to indicate they are mutable over time. In contrast, the query syntax in SQL is declarative.

The imperative/declarative distinction does not apply to protocols like HTTP. Here we would instead talk about side effects or not. PUT has a side effect.

JacquesB
  • 61,955
  • 21
  • 135
  • 189
2

Imperative vs Declarative Programming

Many of the answers here (and the question itself for that matter) fall into the old trap of the "what vs how" metaphor. I think it's the wrong way to look at the question. It doesn't tell us if x = 3 is declarative or imperative. It doesn't tell us about a = b + c...

So let’s take this simple code a = b + c as a basis and view the statement in a few different languages to get the idea:

When we write a = b + c in an imperative language, like C, we are assigning the current value of b + c to the variable a and nothing more. We aren’t making any fundamental statement about what a is. Rather, we are simply executing a step in a process.

When we write a = b + c in a declarative language we are asserting a relationship between a, b and c such that it is always the case that a is the sum of the other two. It’s not a step in a process, it’s an invariant, a guarantee, a declaration of truth.

In essence, declarative code doesn't "do anything," it merely states facts. Imperative code is required otherwise nothing would ever get done. Any language allows you to write in either style.

So when examining code to determine its style don't think "what vs how." Instead ask yourself, "does this code express a fact that is always true regardless of the state of the system, or does it update the state of the system?

Daniel T.
  • 3,053
0

In my view, the imperative/declarative distinction does not exist in the way most people seem to describe it.

What does exist is what nowadays would be recognised as the absence or presence of an "optimising compiler".

SQL is usually considered the canonical example of a "declarative" language. It was conceived during an era when assembly languages still reigned - where every CPU instruction was painstakingly specified.

By contrast to assembly, SQL bears no relation to specifying CPU instructions, and instead the basic work is done by employing a small set of array-oriented operators, and the database engine can fulfil an SQL query using a choice of multiple algorithms and strategies that bear no obvious relation to what the programmer wrote (and yet are provably equivalent).

In this context decades ago, practitioners knew what they meant by the imperative/declarative distinction, even if they don't seem to have bequeathed us with a sound explanation of it.

They meant the fundamental difference between assembly language where you specify every single CPU instruction, and something as comparatively wild as SQL where you write a few lines manipulating an abstract representation of data, and the compiler sort of works out the CPU instructions for itself.

Today however, assembly has long fallen by the wayside, and compilers for all mainstream languages can produce CPU instructions that don't relate in any simple way to the source code. Many languages run in their own VMs. Effectively all mainstream languages are now "declarative" to some significant degree.

SQL remains unique in the mainstream for the sheer breadth of optimisations available to the "compiler" (the database engine), since the entire technology was designed precisely for this purpose from the outset, and has had decades to mature. But it is only a question of degree in this respect, not of fundamental difference.

That said, the question of whether "assignment is declarative or imperative" simply falls away as meaningless, since all languages have some concept of assignment.

Steve
  • 12,325
  • 2
  • 19
  • 35