# Functional Programming illustrated in Python: Part 1

## Simple function composition

*From the **Functional Programming illustrated in Python** series*

Functions calculate values from values. In the simplest case, to combine functions you would take the output from one function and use it as the input to another function.

I am going to take a very simple example:

- The first function
*f()*calculates the square of its input - The second function
*g()*doubles its input - The third function
*h()*adds one to its input

By applying the functions in this order, we can calculate 2*x*²+1.

This is very simple. We start with an input value of 4, square it (16), double it (32), and add one — giving the answer 33. It’s direct application of functions.

Using this notation, we have to nest *f* inside *g* and *g* inside *h* (and *h* inside *print*). The evaluation happens from inside to outside, and hence apparently from right to left. A clearer alternative will be introduced shortly.

For now, you might prefer to bind the intermediate results to variables, so that the flow is from top to bottom, like this:

Or you might not, since you now have the extra variables to think about.

# Composition

Let’s build a new, single function which applies f, g and h in the correct order. We could write this directly:

`def hgf(v):`

return h(g(f(v)))

But that means writing new code every time we want to combine a set of functions. Can we do this in a more reusable way? Yes we can, by means of “function composition” — an operation which combines functions into a new function.

The key part is the function `compose(f1, f2)`

. This accepts two functions as arguments, and returns a single new function, which when invoked, applies f2 and then f1 to a value. The returned function can itself be composed with another function, and so on. We end up with a single function `hgf`

.

This is such a powerful idea that “functional” languages have composition built-in: in Haskell this would be `h . g . f`

It will become important later.

# Chaining the functions

Finally, I’ll show a way to make the data flow linearly from left to right, instead of inside-out and right-to-left.

The trick here is to place the initial value inside a wrapper object, which I’ve called `class Value`

.

On that wrapper I’ve defined a `>>`

operator¹, where `v >> f`

calls `f(unwrapped-v)`

.

In Python this is done by giving the class an operator method: the `>>`

operator normally means “shift bits right”, so the method is called `__rshift__`

.

I also made each function wrap its return value, so these values can be chained².

*Et voilà*, functions are now invoked so that the value is passed from left to right, as if in a pipeline, without having to assign to intermediate variables.

The operator `this >> that`

means “evaluate *this*, then apply *that* to the value”. This is known as a “continuation passing” style: instead of asking a function to return a value directly, you ask it to call some other function that you provide.

The last two lines can be simplified further to:

`Value(4) >> f >> g >> h >> print`

Can you see why? The final `>>`

operator acts on the wrapped value on its left, and calls the function on its right (i.e. `print`

) with the unwrapped value as its argument. Of course, this does introduce an impure function into what was previously a pure functional pipeline.

If you split the lines, you get a familiar top-to-bottom flow:

`(`

Value(4) >>

f >>

g >>

h >>

print

)

However, this is not just a way to make a functional program look pretty. This technique can be expanded into a more powerful way of combining functions that I’ll introduce in the next article.

[1] I really wanted to use the `>>=`

operator, which is what Haskell uses, but Python doesn’t allow that operator to be redefined.

[2] The astute reader will have noticed that I could have re-wrapped the return value inside the `__rshift__`

method as well. However, when you develop this pattern so that the wrapper carries multiple values, then the user’s function will need to return a wrapped value.