DEV Community

Cover image for What is Function Composition
Abdullah Furkan Özbek
Abdullah Furkan Özbek

Posted on • Originally published at blog.furkanozbek.com

What is Function Composition

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));
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

And then a function that uppercases strings:

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

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'
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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!

Links

Top comments (0)