Functional Programming 101 Series

What is Functional Programming?


In this part, we tackle the what of functional programming and defer the question of why and how to later parts.

Functional programming (FP) is about working with pure functions and avoiding side effects. A pure function is a function in the mathematical sense. That is, it is a mapping between two sets, where every element in the first set is mapped to/associated with a single element in the second. In that sense, a pure function has two important properties: i) given the same input, it always returns the same output and ii) it produces no side effects.

There are three mains to have an impure function. Firstly, a global mutation makes a function impure as follows:

def append_one(xs):
...     xs.append(1)
...     return xs

xs = []
xs             # Out: []
append_one(xs) # Out: [1]
xs             # Out: [1]

The variable xs is a global reference and .append is a mutating method, which changes the value of the list. Therefore, we create a side effect that changes the global value of xs as result of calling append_one.

Secondly, a non-deterministic function is, by definition, impure:

import time
time.time() # Out: 1574221354.868907
time.time() # Out: 1574221354.869058

import random
random.random() # Out: 0.2334551699781765
random.random() # Out: 0.7073046734532323

Any function that accepts no argument would necessarily be impure, unless it returns a constant.

Thirdly, any IO operations are side-effectful:

def write(x):
...     with open('temp.txt', 'w') as f:
...         f.write(x)

def read():
...     with open('temp.txt', 'r') as f:
...         out =
...     return out

write('Hello!') # Out: None
read()          # Out: 'Hello!'
write('Hi!')    # Out: None
read()          # Out: 'Hi!'

The write function changes the content of the file temp.txt creating a side effect. The read function reaches out to the file system, which is considered to be mutable and outside the programme, and therefore is usually treated as an impure function.

An astute reader may be wondering, how on earth can we make a useful application without side effects, and specifically IO operations? Most of the applications we build are moving data around. This part only deals with the what of FP and not the how. Skip ahead to the section on “Immutable Core, Mutable Shell” to see how this principle can be applied in practice.