# Functional Programming Concepts: Pure Functions

Functional programming is getting lot of attention these days due to the advantages it offers like parallelism, easier testing, predictability and many others.

Pure functions is a concept mainly used in functional programming languages but it can be applied in any programming paradigm.

What are pure functions ?

There are two conditions that a function must satisfy to be called pure.
Let’s understand these two conditions one by one.

### Given same argument to the function, it should always return same output.

How can we be certain that above mentioned point holds while writing pure functions?

Function must not use state of the program to compute its output.
`x = 5        # x is a global variable`
`multiply(y):    return y*x`

`multiply` is not a pure function because its output is computed using global variable x. If the value of x changes, output of `multiply` function also changes for same input.

`x = 5multiply(2)    # returns 10`
`x = 10         # value of global variable x changed from 5 to 10multiply(2): 20`

In above example input to `multiply` function is same but output has changed depending on the state of the program.

Global variable x is also known as the state of the program because it can be accessed in any part of the program and defines the data associated with a program during its execution.

Since `multiply` function is not giving same output for same input, it is not pure.

To make `multiply` pure, we can pass global variable x as argument to it.

`def multiply_pure(y, x):    return y*x`
`multiply_pure(2, 3)    # returns 6multiply_pure(2, 3)    # returns 6`

No matter how many times we call `multiply_pure` with same input, it will always return same output.

Secondly, a function must not take mutable objects as arguments and should not use it to compute output of the function when working in a concurrent programming environment.

This is because concurrent processes can modify mutable object and ultimately modify the output of a function.
Following example illustrates the above mentioned point:

`# returns length of the list passed as argumentdef compute_length(elements):    return elements.length()`

In between the time when argument `elements` is passed to `compute_length` and length of `elements` is returned by `compute_length` function, it may happen that the length of `elements` list is modified by another process. This is because `elements` is a shared mutable list which can be accessed by multiple processes.

Hence `compute_length` is not pure in concurrent programming environment.

Thirdly, a function must not take any input from the I/O to be pure.
`# takes input from the user and turns it into a greetingdef greet():    str = raw_input()        # take input from user    str = "Hello " + str    return str`

In above written example, output of the function may change depending on the input taken from the I/O.

### Evaluation of the result should not cause any side effects such as mutation of mutable objects or output to I/O devices

Pure function should not mutate any mutable object.

Let’s follow below written example to validate statement written above:

`class Box:    def __init__(self, length):        self.length = length`
`# doubles length of Box object# Assumption: Only box objects are passed def double_length(box):    box.length = box.length * 2     return`
`carton = Box(5)          # a Box object is createddouble_length(carton)    # length of carton is doubledprint carton.length      # prints 10`

Here `double_length` function is impure as it modifies mutable `Box` object.

Doubts ??

Let’s understand it step by step

• `carton(Box object)` is passed by reference to `double_length` function in above example.
• Any changes to `Box` object inside the function will be visible outside the function. So we can say that `Box` object is accessible to whole program, which means that `Box` object is nothing but state of the program.
• And a function must not modify state to be called pure.
Pure function should not output to I/O.
`# prints textdef printer(text):    print “printing…. ” + text `

I/O can be print on a console, write to a database etc.

### Conclusion

Any function which interacts with the state of the program is a potential candidate for causing side effects. State of the program can be global variables, mutable objects, I/O operations etc.

And any function which causes side effects is not pure !!

Please hit the ♥ button if you liked the article so that other Medium users might find it and dig it too.

# More by Saurabh.v Topics of interest