Abdullah Furkan Özbek
Furkan's Notes

Furkan's Notes

What is Function Composition

What is Function Composition

Abdullah Furkan Özbek
·Sep 9, 2021·

3 min read

Play this article

1. What is Compose

In algebra, function composition allows you to apply one function to the output of another function. It looks like this;

Compose Example

We can also apply same thing with javascript.

const compose = (g, f) => x => g(f(x));

2. Example

I can tell, you are a little bit confused. Let me break it down for you;

Let’s say we want to get the name of a user and uppercase it. First of all, we have to write a function that extracts the name of the user;

const user = {name: 'Furkan', lastName: "Cool"}
// Returns -> String
const getUserName = (user) => user.name
getUserName(user)
// 'Furkan'

And then a function that uppercases strings:

// Accepts -> String
// Returns -> String
const upperCase = (string) => string.toUpperCase()
upperCase('Furkan')
// 'FURKAN'

Notice that one function's return value is other function's parameter type.


Compose function will return a function that will executes these two functions.

In our example they are: getUsername & upperCase

const compose = (G, F) => X => G(F(X));

// 'X' in compose
const user = {name: 'Furkan', lastName: "Cool"}

// 'F' in compose
const getUserName = (user) => user.name

// 'G' in compose
const upperCase = (string) => string.toUpperCase()

// Returned function in compose
const getUserNameAndUpperCase = compose(upperCase, getUserName)

// user -> 'X' in compose function
getUserNameAndUpperCase(user); 
//'FURKAN'

3. Scale Problem

The problem with this implementation of compose() is that it takes as parameters just N functions (upperCase & getUserName).

Let’s suppose we want to add another function that returns the full name of the user;

const getUserFullName = (name) => name + " " + user.lastName;
getUserFullName(‘FURKAN’);
// 'FURKAN Cool'

Did you see the problem here?

4. Using compose with reduceRight function

For this case instead of giving N functions and manually changing them, we can use the spread syntax (...) and give an array of functions as an argument to compose function.

// reduceRight calls from right to left instead of left to right
const compose = (...fns) => (initialVal) => fns.reduceRight((val, fn) => fn(val), initialVal);

The reduceRight() method applies a function against an accumulator and each value of the array (from right-to-left) to reduce it to a single value.

5. Full Example

const compose = (...fns) => (initialVal) => {
  return fns.reduceRight((val, fn) => fn(val), initialVal)
};
const user = { name: 'Furkan', lastName: "Cool" }
const getUserName = (user) => user.name
const upperCase = (string) => string.toUpperCase()
const getUserFullName= (name) => name + " " + user.lastName
compose(firstFour, upperCase, getUserFullName)(user);
// 'FURKAN Cool'

Conclusion

Composition is really insteresting subject. Instead of unreadable nested functions, you can organize and chain your functions with each other. And it is super cool!

 
Share this