Table of contents
Open Table of contents
Function Composition
Function Composition is the the process of combining two or more functions to produce a new function. It enables you to build complex operations by composing smaller, more focused functions.
Traditional Approach
This is how traditionally we write programs.
const addOne = value => {
return value + 1;
};
const multiplyByTwo = value => {
return value * 2;
};
const square = value => {
return value * value;
};
console.log(square(multiplyByTwo(addOne(5))));
// or
function compose(value) {
const valAfterAddOne = addOne(value);
const valAfterMultiplyByTwo = multiplyByTwo(valAfterAddOne);
const valAfterSquare = square(valAfterMultiplyByTwo);
return valAfterSquare;
}
compose(5);
Better approach
But there is a better a way to write composed functions. Let’s take an example.
const addOne = value => {
return value + 1;
};
const multiplyByTwo = value => {
return value * 2;
};
const square = value => {
return value * value;
};
function compose(...args) {
return function (val) {
return args.reduceRight((acc, fn) => {
return fn(acc);
}, val);
};
}
console.log(compose(square, multiplyByTwo, addOne)(5));
or you can write in ES6 way
// or
const compose =
(...args) =>
val =>
args.reduceRight((acc, fn) => fn(acc), val);
console.log(compose(square, multiplyByTwo, addOne)(5));
- here we are creating function and it takes functions as an arguments
- it returns function with value
- after that we are reducing array of functions from right to left
As you can see that Function composition is an approach where the result of one function is passed on to the next function, which is passed to another until the final function is executed for the final result.
Now let’s say you want to add one more function divideBy which takes value and divisor as an argument. how would you add this function inside compose function?
const divide = (val, divisor) => {
return val / divisor;
};
const compose =
(...args) =>
val =>
args.reduceRight((acc, fn) => fn(acc), val);
console.log(compose(val => divide(val, 2), square, multiplyByTwo, addOne)(5));
- Here we have to give 2 as parameter
- here we can improve this code by using curried function.
// curried function
const divideBy = divisor => val => val / divisor;
const divideBy2 = divideBy(2);
const compose =
(...args) =>
val =>
args.reduceRight((acc, fn) => fn(acc), val);
console.log(compose(divideBy2, square, multiplyByTwo, addOne)(5));
Most of the modern utility libraries provide compose function.
- Ramda has Compose and Pipe
- Lodash has flow and flowRight
You can also create pipe function as below Just change reduceRight to reduce.
const pipe =
(...args) =>
val =>
args.reduce((acc, fn) => fn(acc), val);