A first step to enter the world of functional programming is to understand the concept of Pure Functions. Pure Functions are the fundamental building blocks of functional programming. In this post, we will discuss what Pure Functions are and why they are important.

What is a Function (from a programming perspective)?

A function is a block of code that takes some input, processes it, and returns some output. In programming, functions are used to encapsulate a piece of code that can be reused multiple times. Functions are the building blocks of any programming language. Here are some examples from different programming languages:

Python:

def add(a, b):
    return a + b

Javascript:

function add(a, b) {
  return a + b;
}

Java:

int add(int a, int b) {
    return a + b;
}

C:

int add(int a, int b) {
    return a + b;
}

What are Pure Functions?

A pure function is a function that satisfies the following two conditions:

  1. Given the same input, it will always return the same output.
  2. It does not have any side effects.

The first condition is very straightforward. If a function returns different outputs for the same input, it is not a pure function. The second condition is a bit tricky. A function is said to have a side effect if it modifies the state of the program or the outside world. For example, if a function;

  • modifies a global variable
  • modifies a parameter passed by reference
  • writes to a file
  • reads from a file (yes, reading from a file is also considered a side effect)
  • makes a network call
  • prints to the console

then it is not a pure function.

Functions in Mathematics

Actually, a pure function is just a function in a mathematical sense. In mathematics, a function is a relation between a set of inputs and a set of possible outputs with some rules (you can check the set theoretic definition of a function). However, if you think about it, you will notice that pure function is nothing but a function in a mathematical sense. Lets look at an example. The function of negation is a function which takes a boolean value as input and returns the negation of that value. In mathematical terms, we can define the negation function as:

\[\neg : Bool \rightarrow Bool\] \[Bool = \{True, False\}\] \[\neg = \{ (True, False), (False, True) \}\]

This function is clearly a pure function. Because, it associates each input with a unique output. Also, it does not have any side effects.

Why are Pure Functions important?

Pure functions have many advantages over impure functions. First of all, if you are using impure functions, you need to be very careful about the order in which you call them. Also, you need to be very careful about the state of the program when you call them. This makes the code very hard to reason about. On the other hand, if you are using pure functions, you don’t need to worry about the order in which you call them. You don’t need to worry about the state of the program when you call them. This makes the code very easy to reason about. Also, pure functions are very easy to test. You can test them by just passing some input and checking the output. You don’t need to worry about the state of the program when you test them.

Also we know that if you compose two pure functions, the result is also a pure function. This means that you can build complex systems by composing simple functions without worrying about the state of the program. This makes the code very easy to reason about.

Examples

def add(a, b):
  print("Hello World")
  return a + b

This function is not a pure function because it has a side effect (prints to the console). If you call this function multiple times with the same input, you will get the same output. But this is not enough to make this function pure.

def add(a, b):
  i = input("Enter a number: ")
  return a + b + i

This function is not a pure function because it has a side effect (reads from the console). Also, if you call this function multiple times with the same input, you may get different outputs because the function reads from the console.

def add(a, b):
  input("Enter a number: ")
  return a + b

This function is also an impure function because it has a side effect (reads from the console).

def add(a, b):
  return a + b

This function is a pure function because it does not have any side effects. If you call this function multiple times with the same input, you will get the same output.

Conclusion

Yes, impure functions are essential in programming. But you can try to make your functions as pure as possible. This will make your code very easy to reason about and test. If you are interested in pure functions, you can check Lambda Calculus and Category Theory. These are the mathematical foundations of functional programming.