Functional Programmer's Toolbox
Obviously, the tools used in functional programming must be functions. There are many of them I like, but I find that there are a few of them which I use every single day:
There is a reason for that, and it is because one can argue that almost all other higher order functions can be build by composing these together.
Sort
The all time classic! The sort
function takes two arguments:
- A list of things that can be compared
- A function that knows how to compare two of those things
The sort
function is implemented as part of the standard library of most functional programming languages, and what is cool about that is that you never have to think about the sorting algorithm itself, it can be any of the following:
You don’t care, because the only thing you have to provide is the comparator function, and there you go, you can sort just about anything you have in your application.
For Example
Given a list of people like this:
- Ruby
- Elixir
- JS
We can sort it like this:
- Ruby
- Elixir
- JS
And you get:
- Ruby
- Elixir
- JS
Map
The map
function takes two arguments:
- A list of things
- A function that takes one argument
What it does is that it goes through all the elements of the list, applies the given function to each element, saves the result, and then returns a new list from those results.
For Example:
If we have a list of numbers and a function like this:
We can get a list of squares of the numbers in the list:
- Ruby
- Elixir
- JS
And we get:
The map
function is very useful, when we want to perform the same kind of processing on all the elements of a list. For example:
-
In a web app we can have a list of user IDs, and we can map over that list with a query function, to get a list of the actual user records.
-
In a navigation app, we can take a list of street addresses, and map over them with a function that returns the geographical coordinates. This way we can display them on the map.
Filter
The filter
function takes two arguments:
- A list of things
- A function that takes one argument and returns
true
orfalse
What it does is that it takes each element of the list, applies the function to that element and checks the result. Then it returns a new list from those elements for which the function returned true
.
For Example:
If we take the list from the previous example:
When we apply the filter function like so:
- Ruby
- Elixir
- JS
We get:
The filter
function can be incredibly useful in situations like this:
-
In a todo app we can filter out the items that are marked as done and show only the items that are yet to be completed.
-
In a movie database app we can choose to display only movies that have rating greater than 9, or only movies that have won the Oscars.
Reduce
The reduce
function is special, because unlike the other functions described here, it takes a list of things, and returns a single value. The arguments for the reduce
function are:
- A list of things
- A function that takes two arguments, and returns one value
- One
initial value
(we will see what this is used for in a second)
The reduce
function is very useful for things like:
- Summing up the elements of a list
- Getting the minimum / maximum element of the list
How It Works
-
It calls the given function for every element in the list.
-
One argument to the call is the current element of the list.
-
The other argument is the result from the previous call.
-
For the very first call we use the
initial value
as the other argument. -
The result of the whole
reduce
function is the result of the last call.
For Example:
Let’s see how we can use reduce
to get the sum of elements in a list such as:
Here is what we do:
-
We pass
0
as theinitial value
to the first call. -
The function we pass to
reduce
returns the sum of its arguments.
Here is a diagram of the whole process:
Here is the example code:
- Ruby
- Elixir
- JS
Take While
The take while
function takes two arguments:
- A list of things
- A function that takes one argument and returns
true
orfalse
It simply starts at the first element of the list, and applies the function to that element.
As long as the result is true
, the elements are added to the resulting list. The first time the function returns false
for a given element, the processing is stopped.
For Example
Given a list of numbers:
When we apply the take_while
function to this list:
- Ruby
- Elixir
- JS
And we get:
The take while
function is very useful when we are dealing with sorted lists, and we want to get only the elements that meet certain criteria. In this scenario, the take_while
function will provide better performance than the filter
function.
The Benefits
-
The separation of concerns is achieved, because, your business logic does not need to know any details of how the higher order function is implemented.
-
Once a higher order function is written and tested, it can be reused many times, without any changes, because it is by nature generic.
-
The higher order functions we discussed are implemented in the standard library of most programming languages, and the principles of how they work are always the same.