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.
Top comments (12)
Nice article. I used to write pipes back in the day using gulp.js. I thought it was custom to gulp, not native to Javascript.
They are not native to JavaScript, they can be used with the help of utility libraries or can be used with the help of a simple implementation first. I'll add that too, thanks.
Oh, thanks for clarification.
@hardiksharma
when I'm use the compose method it throws an error :
Uncaught ReferenceError ReferenceError: compose is not defined
why?
Hey @taralavanya please go through the "Usage in JavaScript" section of this article, you'll understand how to use this.
Got it Thank you :)
Thanks for sharing! Order of function is important in this case, right?
Yes, if you want to apply a series of functions then use them in Pipe in that sequence only. It will go from left to right and perform every function in sequence. In compose also it follows the sequence but from right to left.
Got it
Is Pipe & Compose is a HOF ?
Any function that accepts functions as parameters and/or returns a function is considered as Higher order function, so yes Pipe and Compose are HOFs.
Can we use HOF in compose or pipe method ?