Here’s why developers are in love with functional programming

Functional programming has been around for the last 60 years, but so far it’s always been a niche phenomenon. Although game-changers like Google rely on its key concepts, the average programmer of today knows little to nothing about it.

That’s about to change. Not only are languages like Java or Python adopting more and more concepts from functional programming. Newer languages like Haskell are going completely functional.

In simple terms, functional programming is all about building functions for immutable variables. In contrast, object-oriented programming is about having a relatively fixed set of functions, and you’re primarily modifying or adding new variables.

Because of its nature, functional programming is great for in-demand tasks such as data analysis and machine learning. This doesn’t mean that you should say goodbye to object-oriented programming and go completely functional instead. It is useful, however, to know about the basic principles so you can use them to your advantage when appropriate.

It’s all about killing side effects

To understand functional programming, we need to understand functions first. This might sound boring, but at the end of the day, it’s pretty insightful. So keep reading.

A function, naively stated, is a thing that transforms some input into some output. Except that it’s not always that simple. Consider this function in Python:

This function is dumb and simple; it takes one variable x, presumably an int, or perhaps a float or double, and spits out the square of that.

Now consider this function:

At the first glance, it looks like the function takes a variable x, of whichever type, and returns nothing since there is no return statement. But wait!

The function wouldn’t work if global_list hadn’t been defined beforehand, and its output is that same list, albeit modified. Even though global_list was never declared as an input, it changes when we use the function:

Instead of an empty list, this returns [1,2]. This shows that the list is indeed an input of the function, even though we weren’t explicit about it. And that could be a problem.

Being dishonest about functions

These implicit inputs — or outputs, in other cases — have an official name: side effects. While we were only using a simple example, in more complex programs these can cause real difficulties.

[Read: What audience intelligence data tells us about the 2020 US presidential election]

Think about how you would test append_to_list: Instead of just reading the first line and testing the function with any x, you need to read the whole definition, understand what it’s doing, define global_list, and test it that way. What’s simple in this example can quickly become tedious when you’re dealing with programs with thousands of lines of code.

The good news is that there is an easy fix: being honest about what the function takes as an input. This is much better:

We haven’t really changed much. The output is still [1,2], and everything else remains the same, too.

We have changed one thing, however: the code is now free of side effects. And that’s great news.

When you now look at the function declaration, you know exactly what’s going on. Therefore, if the program isn’t behaving as expected, you can easily test each function on its own and pinpoint which one is faulty.

Woman sitting on couch with MacBook on her lap