Declarative programming: When “what” is more important than “how”
Whether programming an app, IoT software or a computer game – developers have to make a fundamental decision before they write their first line of code: What programming language do they want to use? A variety of languages is available, but all of them can be assigned to two fundamental programming paradigms: declarative programming and imperative programming.
What is declarative programming?
There is no one specific definition of the paradigm, but all definitions agree on one thing: A characteristic feature of declarative programming languages is that they always describe the desired end result rather than outlining all the intermediate work steps. In declarative programming, the solution path to reach the goal is determined automatically. This works well, provided the specifications of the final state are clearly defined and an appropriate implementation procedure exists. If both of these conditions are met, declarative programming is very efficient.
Since declarative programming does not specifically describe the “how” but works at a very high level of abstraction, the programming paradigm also leaves room for optimization. If a better implementation procedure is developed, the integrated algorithm can identify and use it. This makes the paradigm futureproof. The procedure for how the result is to be achieved does not have to be set in stone when writing the code.
The best-known declarative programming languages are:
- Prolog
- Lisp
- Haskell
- Miranda
- Erlang
- SQL (in the broadest sense)
The different declarative programming languages can, in turn, be divided into two paradigms: functional programming languages and logic programming languages.
However, in practice, the boundaries are frequently blurred and elements of both imperative programming – with its sub-types procedural, modular, and structured programming – and declarative programming are used to solve problems.
Imperative vs declarative programming
The imperative programming paradigm (command-based paradigm) is the older of the two basic paradigms. Unlike in declarative programming, in this case, the developer specifies in the source code precisely what the computer should do, step by step, to achieve the result. The focus is on the “how” of the solution path. For example, this approach can be found in Java, Pascal, and C. By contrast, in declarative programming the “what” of the solution is described directly.
As an example, let’s apply the idea to furniture assembly: While imperative programming provides instructions for assembly, declarative programming provides a picture of the finished piece of furniture as a template.
Instead of leaving the “how” of implementation open with functions, in imperative programming there are variables, which are changed at runtime. This makes the code longer but also more understandable than the truncated and very abstract form of the declarative style.
Declarative programming example
One of the strengths of declarative programming is its ability to describe problems more briefly and succinctly than imperative languages.
If we want to output a list of first names, in PHP this can be described with just one line of code using declarative programming – as the example shows – while the imperative method requires five lines.
Imperative programming
$participantlist = [1 => 'Peter', 2 => 'Henry', 3 => 'Sarah'];
$firstnames= [];
foreach ($participantlist as $id => $name) {
$firstnames[] = $name;
}
Declarative programming
$firstnames = array_values($participantlist);
Advantages and disadvantages of declarative programming languages
These days, the declarative programming style is used in a variety of cases, even if not in its purest form. However, the method is not suitable for all uses.
Declarative code is characterized by a high level of abstraction. This enables developers to represent complex programs in a compressed form. But the more sophisticated the application, the greater the danger that the code becomes so convoluted that it can only be read by the developer who originally wrote it. For companies that want to be able to maintain and develop applications without having to rely on a single person’s knowledge, this presents a challenge. External developers have to carefully read and work out the declarative code until they understand the structure and have solved any problems.
However, the level of abstraction in declarative programming also offers advantages. Because implementation is clearly delineated from the system using an algorithm, maintenance can be performed independently of application development. Interruptions of day-to-day operations are reduced to a minimum. At the same time, optimization is easier because the algorithm used allows new methods to be integrated. One disadvantage of algorithm use is that this kind of formulaic solution is often insufficiently equipped to deal with specific characteristics of individual applications.
Not so much a disadvantage as a challenge is the conceptual model of declarative programming. Thinking in terms of solution states contradicts natural human thought processes. People tend to think in terms of processes moving towards a goal rather than starting from a goal and working backward. This requires developers to rethink and accustom themselves to the concept, which can initially slow down problem-solving. However, once the new mindset has been learned, the declarative approach can capitalize on its strengths.
Another advantage of development starting from the description of the problem is that teams can outline solution models rapidly. Ultimately, specific programming of the implementation can take place later. The declarative style is thus well suited for prototyping in agile software development.
Advantages | Disadvantages |
---|---|
Short, efficient code | Sometimes hard to understand for external people |
Can be implemented using methods not yet known at the time of programming | Based on an unfamiliar conceptual model for people (solution state) |
Easy optimization as implementation is controlled by an algorithm | Hard to take characteristics of individual applications into account during programming |
Maintenance possible independent of application development |
In practice, mixed forms of the paradigms are often used these days, with declarative programming languages being supplemented with imperative methods. However, this increases susceptibility to errors and can impair the legibility of the code.