Duccio Marco Gasparri

A neat example of functional programming

I am writing a software that proposes a list of items on screen, each one with a number associated to it. Then it lets the user input what items they desire to select, space separated.

We all know that user input is a great source of uncertainty, and several checks are needed. In particular, it needs to clean spurious characters (spaces, new lines, etc.), check if it is really an integer (not a ‘123abcd’ string), convert it into an integer, and check again if that integer is in the list of items.

In Python, all those checks and cleaning is done by the following code:

The code is already at its third level of nesting, just for the checks.

Functional programming imposes a change in attitude. It requires the checks and conversions to be embedded in the list you bring forward, as they need to be as transparent as possible to the end user of the object.

So, not:

but

If we have a function check(single_item) and we have a unchecked_items_list [‘item1′,’item2’,’item3], we need to find a way to go from the incorrect composition:

to the formally correct composition:

As trivial as it might seem, FP forces you to think thoroughly at what that conversion actually means: you start with a type of list, but you do not end up with the same type of list.

In Python, that becomes:

map applies the function to all of the elements of a list, and filter reduces the list by eliminating from it the items whose check returns False.

The first version was dependent on two _if_s, and if you wanted to mentally follow the code, you had to consider three possible paths of execution: i) one if the entry was not composed by digits; ii) one the entry was composed of digits but was not in the list; iii) one the entry was all digits and it was in the list.

In FP, we:

The functional programming version of the code appears scary to the unexperienced programmer, but at a closer look, one thing emerges: it has one and only one path of execution. No conditionals, no ifs, no split paths of execution.

The loop is always executed for all the valid items in the original list. If no item was valid, then the list is simply empty.

Now, scale that to the size of a whole computer program composed of thousands of lines of code: your program starts at line 1, ends at line X, and follows the same identical path of execution, always.

It appears more difficult at a first glance, but in the end, by implementing this kind of rigorous formalism throughout the code, you can improve its readability and reduce errors.