Improve Imperative design in control statements with a Functional Design

Imperative code is hard to read, forces the designer to mutate state and is a breeding ground for hard to find bugs. But why are Programmers attracted to writing in an “Imperative style”? May be because that is because they started their careers in procedural and object oriented languages and Imperative style comes natural to them. Imperative design coupled with the principles of Functional programming can go a long way in simplifying t

“Perfection is achieved when there is nothing left to take away.”

 Antoine de Saint-Exupéry

In Software Design, perfection and simplicity go hand in hand. Writing in Imperative style can be faster but building the necessary abstractions to write following a Declarative style takes time and patience. And we all seem to lack these virtues these days! Here’s another quote that’s apt for this situation

“I apologize for such a long letter – I didn’t have time to write a short one.”

Mark Twain

Let the language do the heavy lifting

When you mutate the state, you are responsible for making sure that you don’t introduce any bugs in your design. However if you embrace a declarative approach, you let the language do the heavy lifting and avoid introducing bugs.

Declarative style is more readable for half the work

Not only a Declarative style more readable, but you can accomplish the same work with fewer lines of code.

Functional programming makes you write better code even when you write in pure OOP

You may be forced to write in a non Functional language for various reasons. But learning to code in a Declarative style or using a Functional programming language can help you borrow the principles (Data immutability, Pure functions) and help you write better code no matter in which language you have to code in.

Here’s an example in Kotlin that illustrates how bad imperative style of programming can be.

//A bad solution
var i = maxPerRequest
var c = 2
while (i < searchForIssues.total && i < total) {

    log.info("Request #$c Quering API jql $jql, for issues $i to ${i + maxPerRequest} out of ${searchForIssues.total}. " +
            "Total limit is set to $total entries")
    val searchIssues = jira.searchIssues(jql, null, maxPerRequest, i)
    jiraQaps.addAll(searchIssues.issues)
    log.info("Waiting $pauseInterval miliseconds before making next call")
    c++
    i += maxPerRequest
    if(i < searchForIssues.total && i < total)
        Thread.sleep(pauseInterval.toLong())
}

Fortunately, Kotlin provides constructs that can help clean this up. Here’s one way to remove imperative elements and make it more readable.

//A better solution
val limit = if( searchForIssues.total < total)  searchForIssues.total else total

 for (i in maxPerRequest until limit step maxPerRequest) {
     log.info("Quering API jql $jql, for issues $i to ${i + maxPerRequest} out of ${searchForIssues.total}. " +
             "Total limit is set to $total entries")
     val searchIssues = jira.searchIssues(jql, null, maxPerRequest, i)
     jiraQaps.addAll(searchIssues.issues)
     log.info("Waiting $pauseInterval miliseconds before making next call")
     Thread.sleep(pauseInterval.toLong())
 }

Notice that there are no more variables in the above implementation. It’s more readable, conveys the intent to the reader so it makes it easier to maintain or change. Kotlin makes it easy to make something final unlike Java. This is important for psychological reasons. People tend to follow best practices when you make it easier for them to do so! Who likes to type in “public static final……”?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: