Declarative Programming

Most developers are very familiar with writing imperative programs (even though they may not know it by that name). In this article, I will introduce you to an alternative style of programming called declarative programming. Proper declarative programs are easier to read, understand, and maintain.

As professionals, we should be striving to write better programs each day. If you cannot look at programs you wrote three months ago with a critical eye and notice things that could be better, then you have not improved and are not challenging yourself. I challenge you to write programs that are easier to read and understand by using declarative programs.

Contents

First, it is important to understand what declarative programs are and how it relates to imperative programs.

To understand this we have to first understand what is imperative programming.

What Is An Imperative Programming?

In computer science, imperative programming is a programming paradigm that uses statements that change a program’s state. 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 programs describe how something is done whereas declarative programs describe what is being done.

Imperative programs are generally difficult to read and understand. For example:

 1 using System;
 2 
 3 class Example
 4 {
 5     static void Main()
 6     {
 7         var sum = 0;
 8         for (var i = 0; i < 100; i++)
 9         {
10             if (i % 2 == 0)
11             {
12                 sum += i;
13             }
14         }
15         Console.WriteLine(sum);
16     }
17 }

It is not immediately apparent what this program does. Only through careful examination can we deduce that it prints the sum of all even numbers between 0 and 99.

Now, let us see how declarative programming will help us out here,

What Is A Declarative Programming?

In computer science, declarative programming is a programming paradigm—a style of building the structure and elements of computer programs—that expresses the logic of a computation without describing its control flow.

This is how the above program would be implemented using a declarative style:

 1 using System;
 2 using System.Linq;
 3 
 4 class Example
 5 {
 6     static void Main()
 7     {
 8         var sum = Enumerable.Range(0, 99)
 9                       .Where(i => i % 2 == 0)
10                       .Sum();
11         Console.WriteLine(sum);
12     }
13 }

Obviously, the second example is different, but is it better? I believe it is. We have condensed the example into a single expression and the expression is significantly easier to understand. The name of each method is used to express the intention of that portion of the program. Rather than looping with a classic for-loop I have used the newer Enumerable.Range method. This not only better expresses my intentions but also gives me a starting place from which I can easily stream the numbers through a filter (the Where method) and finally aggregate them with Sum.

But I still think this code could be better. Let me do one last thing to make our program even more declarative:

 1 using System;
 2 using System.Linq;
 3 
 4 class Example
 5 {
 6     static void Main()
 7     {
 8         var sum = Enumerable.Range(0, 99)
 9                       .Where(isEven)
10                       .Sum();
11         Console.WriteLine(sum);
12     }
13 
14     static bool isEven(int number)
15     {
16         return number % 2 == 0;
17     }
18 }

This change is subtle but important. We have moved the somewhat cryptic expression that tests for evenness into its own method. Since this method has a single responsibility and is clearly named, it is ideal for inclusion in our declarative expression. It is important to understand that declarative programs don’t necessarily mean fewer lines of code. Declarative programs are characterized by how expressive it is. By moving the test for evenness into its own method we may have increased the line count of the program, but we have also greatly improved the readability of the programs as well.

Declarative programming is nice because it can help simplify your mental model* of code, and because it might eventually be more scalable.

I am a .NET developer and if you are too, you will find this kind of programming style everywhere in .NET.

For example, let’s say you have a function that does something to each element in an array or list. Traditional code would look like this:

1 foreach (object item in MyList)
2 {
3    DoSomething(item);
4 }

No big deal there. But what if you use the more-declarative syntax and instead define DoSomething() as an Action? Then you can say it this way:

1 MyList.ForEach(DoSometing);

This is, of course, more concise.

Declarative Programming Examples

Below are some examples I found from my peers:

Javascript Example

Imperative:

 1 var today = new Date();
 2 var decimalDate = today.getHours() + (today.getMinutes() / 60);
 3 
 4 var timeOptions = [...Array(48).keys()].map(n=> n * 0.5)
 5 .filter(n=>n > decimalDate)
 6 .map(n=>n*60)
 7 .map(time_convert);    
 8                 
 9 timeOptions.push('23:59');
10 
11 console.log(timeOptions) 
12 /* 
13 display:
14 ["22:00",
15 "22:30",
16 "23:00",
17 "23:30",
18 "23:59"]
19 */
20 
21 function time_convert(num)
22 { 
23   var hours = Math.floor(num / 60);  
24   var minutes = num % 60;
25   minutes=parseInt(Math.ceil(minutes));
26   if(minutes < 10) minutes = `${minutes}0`;
27   return hours + ":" + minutes;         
28 }

Declarative:

 1 var decimalHours = [...Array(48).keys()].map(n=> n * 0.5);
 2 var timeOptions = decimalHours
 3 .filter(isTimeInFuture)
 4 .map(decimalToSeconds)
 5 .map(secondsToTimeFormat);      
 6                 
 7 timeOptions.push('23:59');
 8 
 9 console.log(timeOptions);
10 /* 
11 display:
12 ["22:00",
13 "22:30",
14 "23:00",
15 "23:30",
16 "23:59"]
17 */
18 
19 function decimalToSeconds(decimalTime) 
20 {
21   return decimalTime * 60
22 }
23 
24 function isTimeInFuture(decimalTime) 
25 {
26   var now = new Date();
27   var decimalNow = now.getHours() + (now.getMinutes() / 60);
28   return decimalTime > decimalNow
29 }
30 
31 function secondsToTimeFormat(num)
32 { 
33   var hours = Math.floor(num / 60);  
34   var minutes = num % 60;
35   minutes=parseInt(Math.ceil(minutes));
36   if(minutes < 10) minutes = `${minutes}0`;
37   return hours + ":" + minutes;         
38 }

I hope that I have shown how you can improve your programs by making it more declarative. If you strive to write more declarative programs you will end up with better software that is easier to read, understand, and maintain.

If you are already doing it do send me your declarative style examples in the comment below and I will love to add those up in my article.

Further Reading

Declarative Programming
Share this

Subscribe to Code with Shadman