A lot of blogs, books, online tutorials, videos, and courses found on the World Wide Web start with a common statement, saying that Redux was built on the top of functional programming. The statement is valid, which means that developers like us need to understand the concept of functional programming.
Let's point out some of the important characteristics of functional programming, as follows:
- Functions are first class objects
- Functions can be chained together
- Functions can be passed as arguments
- Functions, recursions, and an array can be used to control the flow
- We can use pure, higher-order, closure, and anonymous functions
- We can utilize several helper functions, including
map
,filter
, andreduce
In functional programming, functions are considered first class citizens. This means that the language does support passing functions to other functions as arguments, and returning them as the values for other functions. Moreover, they can also be assigned to other variables, or stored in some data structure.
An example of calculating body mass index (BMI), provided the height (in meters) and weight (in kilograms), can be created via the following method. The function is stored in a variable named bmi
and can be called whenever it is required:
const bmi = (weight, height) => weight / (height * height);
A variable can be added to any object. Since a function is stored in a variable, it can also be added to objects, as follows:
const myCalculator = { bmi: (weight, height) => weight / (height * height) };
Similarly, we can add it to an array, as follows:
const myCalculator = [ Bmi => (weight, height) => weight / (height * height) ];
Functions can be used as arguments for other functions. Let's use the preceding bmi
function to check whether a person has an obesity issue. According to the BMI scale, someone with a bmi
between 30.0
and 54
is said to have obesity. We will pass a function as an argument, as follows:
const bmi = (weight, height) => weight / (height * height); const hasObesity = (bmi) => bmi >= 30.0 && bmi <=54; console.log(hasObesity(bmi(100, 2.2)));
Another common scenario is when a function returns another function, as follows:
const bmi = (weight, height) => weight / (height * height); const calculator = () => { return bmi; };
Higher-order functions (HOF) is the fanciest term you will be hearing when getting started with functional programming. Higher-order functions are functions that take functions as arguments or return functions. By now, we have already been consuming such functions. Remember Array.reduce()
, Array.filter()
, and Array.map()
? These are all higher-order functions. In the Redux library, we are consuming some of the HOF, too (such as connect()
).
The most common definition of a pure function is a function that does not have side effects. This is to say that the returned value of a pure function is not affected, influenced, or changed by anything other than its input parameters. Provided the same input, the pure function always generates the same output. An example is as follows:
const sum = (a, b) => a + b;
This is an example of a pure function. Assuming that you call the function sum(6,9)
, the result is always 15
, irrespective of the number of times that you run the function. You can be confident, if you are calling a pure function with the same input, that you are always going to get the same output, which means that the output is predictable. An example of an impure function is the following square
function. In addition to returning the square of the number, the function might be updating the number in a database:
function square(number) { updateNumberInDB(number); return number * number; }
A composition is a very important concept of functional programming; it is how we create a higher-order function by consuming and combining simpler functions.
Let's just use the sum
function that we defined previously. We can split the sum
function into the following composition:
const sum = a => b => a + b sum(2)(5)
Any function can be transformed into a composable function via the concept of currying. Explaining these fundamental functional concepts is beyond the scope of this book, and we suggest that you get familiar with functional terms as much as possible, in order to get a full understanding of Redux and React. We will consume a composition function from Redux, called compose
, in upcoming chapters.