One of my least favourite concepts in JavaScript had to be the compose and pipe functions, I mean, they are great functions and definitely save a lot of time, but while learning it, it just looked like a bunch of functions returning each other, it was difficult to understand what was really happening.
In this article, we'll be going over the compose function line by line while I explain like to a toddler.
Before we start, you atleast need a little knowledge of javaScript.
What is a compose function
The compose function is a higher-order function that takes two or more functions as arguments and returns a new function that applies these functions in a right-to-left order. Basically, a compose function receives a bunch of functions as argument and then sends them to another function inside of itself which applies them from right to left using the reduceRight method in javaScript. et's dive right into it.
Given a typical compose function;
function compose(...funcs) {
return function(arg) {
return funcs.reduceRight((accum, fn) => {
return fn(accum);
}, arg);
};
}
Let's break it down line by line and digest it
function compose(...funcs) {
This is the beginning of a function called compose(the function doesn't have to be called compose). It takes any number of arguments (functions) and stores them in an array using the spread operator(...).
return function(arg) {
Here we return a function which recieves a single argument, the argument it recieves is going to be the element which these functions will be exercuted on.
return funcs.reduceRight((accum, fn) => {
This line starts a reduceRight method on the funcs array(remember the array was created virtually, using spread[...] operator), which applies the callback function to each element in the array, starting from the right side. If you don't understand, don't fret, I'll still explain how the reduce function works as you read down.
return fn(accum);
This line applies each function in funcs to the accum variable. accum is initially set to the value of arg (the argument passed to the returned function), and it gets updated each time a function in funcs is applied to it.
}, arg);
};
}
Finally, we set the initial value of accum to the value of arg.
The reduceRight function
In JavaScript, the reduceRight
method takes a callback function as its first argument, which is used to apply a given operation to each element in the array, and reduce the array to a single value. The callback function takes two arguments: the accumulator (which starts as the last element in the array) and the current value (which starts as the second-to-last element in the array).
In the compose
function, the callback function being used with reduceRight
is an arrow function with two parameters: accum
and fn
. accum
is the accumulator that gets passed from one iteration to the next, and fn
is the current value being processed by the reduceRight
method.
The callback function returns the result of applying fn
to accum
. This means that each function in funcs
is being applied to the previous result, and the final result is the output of the last function in the array after it has been applied to the previous result.
How the compose function executes
Let me walk you through an example callstack for the compose function to demonstrate how it works.
Let's say we have the following functions:
function addOne(x) {
return x + 1;
}
function double(x) {
return x * 2;
}
function square(x) {
return x * x;
}
And we call compose like this:
const composedFunction = compose(square, double, addOne);
const result = composedFunction(2);
console.log(result); // Output: 36
Here's what happens step by step:
- we call compose with the arguments
square
,double
, andaddOne
const composedFunction = compose(square, double, addOne);
- Inside the compose function, the
reduceRight
method is called on thefuncs
array([square, double, addOne])
. The initial value of the accumulator (accum
) is set to the value of the argument passed to the returned function (arg
), which in this case is 2.
result = 2;
- The first iteration of the
reduceRight
method starts, withfn
set toaddOne
. The function is called withaccum
as the argument, and returns the value 3. This becomes the new value ofaccum
.
accum = addOne(accum); // result = 3
- The second iteration of the
reduceRight
method starts, withfn
set todouble
. The function is called withaccum
as the argument, and returns the value 6. This becomes the new value ofaccum
.
accum = double(accum); // result = 6
- The third and final iteration of the
reduceRight
method starts, withfn
set tosquare
. The function is called withaccum
as the argument, and returns the value 36. This becomes the final value ofacuum
.
accum = square(accum); // result = 36
The returned function from compose
is called with the argument 2. This function applies each function in the funcs array to the argument in a right-to-left order. First, addOne
is called with the argument 2, which returns 3. Then, double
is called with the argument 3, which returns 6. Finally, square
is called with the argument 6, which returns 36
So, in summary, the compose function takes any number of functions as arguments and returns a new function that applies these functions in a right-to-left order. The returned function takes a single argument and applies each function in the provided array to it, starting from the right side. By doing this, we can create a new function that is composed of multiple smaller functions, which can make our code more modular and easier to read.
As usual thank you for reading and I hope you got value for your time. Follow me @frontend_jedi to find more educating reads. Follow me on twitter @Frontend_Jedi let's connect and grow together.
Top comments (0)