Compose( ) and Pipe( ) in JavaScript
Hardik Sharma
Posted on July 17, 2023
Compose
and Pipe
are among the most powerful concepts in functional programming in JavaScript. And, can be very helpful while programming in JavaScript. This article will help you understand them better
Compose
Let us assume we want to get the name of a person. So we have to write a function that extracts the name:
const person = { name: 'Hardik', age: 25};
const getName = (person) => person.name;
getName(person);
// 'Hardik'
We want the name in uppercase, we write a function for that also:
const upperCase = (string) => string.toUpperCase();
upperCase('Hardik');
// 'HARDIK'
If we want both the actions being taken on our person
, then we need to nest the functions
upperCase(getName(person));
Now we can compose the two functions to have just one function that executes both actions: Get the name and uppercase it.
So we implement compose
like:
const getNameInUpperCase = compose(upperCase, getUserName)
getNameInUpperCase(person);
//'HARDIK'
It executes them from right to left.
But the problem with this implementation of compose
is that it only takes two functions as parameters.
Let's say we want more than two functions, this is when we need to use Pipe
.
Pipe
Pipe
is exactly like compose
but it goes from left to right and can have multiple functions as parameters.
We already have two functions to get the name and uppercase a string. Now, let's say we have a function to get only 4 characters of a string.
const getSubString = (string) => string.substring(0, 4);
getSubString('Hardik');
// 'Hard'
And then let's say we have a function to reverse strings.
reverseString = (string) => string.split('').reverse().join('');
reverseString('Hardik');
// 'kidraH'
Now, if we want to apply all this on a single object by nesting
reverseString(getSubString(getNameInUpperCase(getName({ name: 'Hardik' }))));
// 'DRAH'
But this is too much and can get more crowded if we have more functions.
This is where Pipe
comes into play
pipe(
getName,
getNameInUpperCase,
getSubString,
reverseString
)({ name: 'Hardik' })
// 'DRAH'
Works wonderfully from left to right and applies the next function to the response of the previous one. Will go to every function in sequence and in a much cleaner way.
Usage in JavaScript
Both Pipe
and Compose
are not native to JavaScript and can be used with the help of some utility libraries like lodash, ramda and so on.
But we can also use a simple implementation ourselves to use both the functions in JavaScript without importing any libraries.
For Pipe:
const pipe = (...fns) => (accValue) =>
fns.reduce((currentValue, currentFunction) =>
currentFunction(currentValue), accValue);
In this implementation we provide our list of functions and our input to our custom pipe
which uses reduce
to implement each function and return its result and keeps an accumulated value to be used by the function that's next in line.
similarly for Compose:
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
Conclusion
Hopefully, this article clarified some of your doubts and helped you understand how Compose
and Pipe
work.
You can now create functions working as factory conveyor belts that receive data, and these data go through all these different functions until we finally obtain our output.
Posted on July 17, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.