Contents

Declarative vs Imperative Programming

Declarative programming

Many languages that apply this style attempt to minimize or eliminate side effects by describing what the program must accomplish in terms of the problem domain, rather than describe how to accomplish it as a sequence of the programming language primitives[2] (the how being left up to the language’s implementation). This is in contrast with imperative programming, which implements algorithms in explicit steps.[3]

Imperative programming

In much the same way that the imperative mood in natural languages expresses commands, an imperative program consists of commands for the computer to perform. Imperative programming focuses on describing how a program operates step by step, rather than on high-level descriptions of its expected results.

The term is often used in contrast to declarative programming, which focuses on what the program should accomplish without specifying all the details of how the program should achieve the result.[1]

In short, with imperative programming, you tell the compiler what you want to happen, step by step.

With declarative programming, on the other hand, you write code that describes what you want, but not necessarily how to get it (declare your desired results, but not the step-by-step).

For example, let’s examine Where method in the LINQ library from the dotnet/runtime repository.

Examples

Where

Filters a sequence of values based on a predicate.

Usage:

var fruits =
    new List<string> { "apple", "passionfruit", "banana", "mango",
                    "orange", "blueberry", "grape", "strawberry" };

var query = fruits.Where(fruit => fruit.Length < 6);

foreach (var fruit in query)
{
    Console.WriteLine(fruit);
}
/*
 This code produces the following output:

 apple
 mango
 grape
*/

As you can see, in the example above, we told it to fetch items less than 6 characters from the list. We can think of it as going to a restaurant and ordering food.

If there was no such method, how would we do the same thing? It would probably be something like the following.

var fruits =
    new List<string> { "apple", "passionfruit", "banana", "mango",
                    "orange", "blueberry", "grape", "strawberry" };

foreach(var fruit in fruits) {
    if (fruit.Length < 6) {
        Console.WriteLine(fruit);
    }
}
/*
 This code produces the following output:

 apple
 mango
 grape
*/

Both give the same output, but the first one is an example for declarative programming and the second one is for imperative programming because in the second we are telling what should happen step by step.

As a result, we can deduce that you should always write code according to declarative programming, but this is not the case because the code that actually does the details of the actual work must be somewhere, just like the Where method does in the code below.

public override bool MoveNext() {
    switch (_state) {
    case 1:
        _enumerator = _source.GetEnumerator();
        _state = 2;
        goto
    case 2;
    case 2:
        while (_enumerator.MoveNext()) {
            TSource item = _enumerator.Current;
            if (_predicate(item)) {
                _current = item;
                return true;
            }
        }

        Dispose();
        break;
    }

    return false;
}

As a result, one of the reasons functional programming and functional libraries are more declarative is because they have abstracted away loops and list creations, hiding all the implementation details (most likely imperative code with loops) behind the scene.

In any program, you will always have both imperative and declarative code. We should aim to hide all imperative code behind the domain-specific abstractions so that other program parts can use them declaratively.

References

  1. https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.where?view=net-6.0
  2. https://github.com/dotnet/runtime/blob/main/src/libraries/System.Linq/src/System/Linq/Where.cs
  3. https://stackoverflow.com/questions/1784664/what-is-the-difference-between-declarative-and-imperative-paradigm-in-programmin