Function composition and the making of compose
Tags: javascript, functional, tutorial
Published: 2019-05-09 10:04:03

---
title: Function composition and the making of compose
published: true
description: or how to use a Bluebird
tags: #javascript, #functional, #tutorial
---
<img src="https://thepracticaldev.s3.amazonaws.com/i/4wuxwt9rft2vfvl251c7.jpg" alt="lego blocks">
<small>Image by <a href="https://pixabay.com/users/StockSnap-894430/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=2569802">StockSnap</a> from <a href="https://pixabay.com/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=2569802">Pixabay</a></small>


## Who is this for?

Any one who is interested in functional programming in JavaScript and would like to understand how a compose function may be derived and all for the sake of greater understanding. It is not intended for the experienced fp programmer. The compose function that we will make here is not even intended for production use.

## Intro
In this post I will take the following steps
 - show the normal use case for Array.prototype.reduce
 - show how we can .reduce an array of functions
 - make a generic compose function from a decoupled reduce function
 - test this compose on a simple mathematical problem 
 - finally, use it to solve the shopping cart example in TK's post, see below

As I would like to keep this post as short as possible, I would recommend that if you are unfamiliar with any of the following terms: first class functions, higher order functions, pure functions, currying, partial application, immutability and folding, then please read these excellent posts here on DEV...

 - [Functional Programming Principles in Javascript by TK](https://dev.to/leandrotk_/functional-programming-principles-in-javascript-26g7)
 - [Learn To Fold Your JS Arrays a series by Neil Syiemlieh](https://dev.to/mebble/learn-to-fold-your-js-arrays-2o8p)
 
 Additionally, please read  this post by Joel Thoms on method decoupling on hackernoon.com.
 - [Functional JavaScript: Decoupling methods from their objects by Joel Thoms](https://hackernoon.com/functional-javascript-decoupling-methods-from-their-objects-aa3ca13d7ae8)
 
 So now you know what is to come, the rest is in the detail.

## A simple start
Here is the normal use case for reduce in JS

```javascript

const  sum = (a, b) => a + b

const  sumIntegers = [1,2,3,4,5].reduce(sum, 0)
// => 15

```
Here we are summing the list of integers. In code order we assign to sumIntegers the result of an array of integers applied to the reduce method with the callback function, or "***reducer***", sum; finally we must supply an ***empty or identity value*** as the last argument to reduce. It is important to understand that the *identity value* has a relationship with respect to the reducer it serves. For the sum reducer, identity is 0:

	0 + (a number) = that number
	ie.  0 + 1 = 1,
	and 0 + 2 = 2

for multiplication the identity value is 1:
	
	1 x (a number) = that number
	ie. 1 x 2 = 2
	and 1 x 4 = 4

This means that the identity value  __has no effect__ on the first iteration of the reduction. 

## Let's ramp it up a notch
In JS, functions are [first class](https://hackernoon.com/javascript-and-functional-programming-pt-2-first-class-functions-4437a1aec217). They can be essentially treated like any other data type and can be reduced or folded, just like the list of integers above; this in fp, when applied to functions, is what is termed function composition.

But, if we are going to use reduce on an array of functions then what will be our reducer and what will be it's associated identity value? Well, it turns out that, they both must be functions, because we are reducing functions. This reducer is commonly referred to as **composeB**, while the empty value is called **Identity**. Incidentally, these as part of a group of functions are called **combinators**. Take a look at this github page of common [combinators](https://gist.github.com/Avaq/1f0636ec5c8d6aed2e45), the B or composeB combinator is what we will be using in this next step (along with Identity). The B stands for Bluebird and originates from a book by [Raymond Smullyan](https://en.wikipedia.org/wiki/Raymond_Smullyan "Raymond Smullyan"), a mathematician who wrote a book called [To Mock a Mockingbird](https://en.wikipedia.org/wiki/To_Mock_a_Mockingbird "To Mock a Mockingbird"); a book about combinatory logic.

It should be noted that composeB is **limited** to accepting **only** two functions, whereas the compose function we will be building here will accept a list of more than two functions.

So what does composeB and Identity look like in JS? Here they are...

```javascript
const  Identity  =  x  =>  x
// pass in a value and you get the same value back.

const  composeB  = (f, g) =>  x  =>  f(g(x))
// composes two functions together. Pass in a function f and a function g then apply g to data x and then run the result of that through f to get a final result.
```

So now we can apply these two functions to Array.prototype.reduce and just so that it can be demonstrated, let's add 5 to what ever number is passed in and then double the result.

For this we need...

```javascript
const  add = a => b => a  +  b
// add is a curried function

const  add5 = add(5)
// make a new function add5

const  double = a => a * 2
// it speaks for itself
```

Now the thing with compose is that it reads from right to left, so ...

```javascript
const add5ThenDouble  = [double, add5].reduce(composeB, Identity)

console.log(typeof  add5ThenDouble)
// => function
```

So, now we have a **add5ThenDouble** function let's apply it...

```javascript
console.log(add5ThenDouble(6))

// => (6 + 5) * 2 => 22

```

Well it works, but wait a minute, what we actually want is a generic function called compose that will take a list of functions. For this we will need to decouple .reduce from Array.prototype like this...
```javascript
const reduce = (f, i) => coll => Array.prototype.reduce.call(coll, f, i)
```
You can see that this is a curried function: the double =>'s tells us that. We take the reducer function and it's empty value and then the collection(an Array in JS)

Note: Notice how our functions take as their last argument the data. This is important.

So, applying this to make a generalized compose function we do...
```javascript
const compose = reduce(composeB, Identity)
```
And there we have it, so let's do the above again using compose... remembering that this compose has been derived from reduce so it expects an array of **[pure](https://hackernoon.com/javascript-and-functional-programming-pt-3-pure-functions-d572bb52e21c)** functions.

```javascript
const  add5_ThenDouble = compose( [double, add5] )
// Remember, it reads right to left

console.log(add5_ThenDouble(6))
// => 22
```
## More than a Bluebird in the hand...
Now we have got our compose function let's use it to solve the last example in TK's post

[Functional Programming Principles in Javascript by TK](https://dev.to/leandrotk_/functional-programming-principles-in-javascript-26g7)

 To do this we will need, first the shoppingCart data

```javascript
 let  shoppingCart  = [
  { productTitle: "Functional Programming", type: "books", amount: 10 },
  { productTitle: "Kindle", type: "eletronics", amount: 30 },
  { productTitle: "Shoes", type: "fashion", amount: 20 },
  { productTitle: "Clean Code", type: "books", amount: 60 }
]
```
a curry function would be nice...

```javascript
const  curry = f => (...args) =>
  args.length >=  f.length
  ? f(...args)
  : curry(f.bind(undefined, ...args))
```

A couple of other decoupled functions, wrapped by curry.

```javascript
const map = curry((fn, xs) => Array.prototype.map.call(xs, fn))
const filter = curry((fn, xs) => Array.prototype.filter.call(xs, fn))
```

and finally, TK's helper functions.

```javascript
const sumAmount = (acc, amount) => acc + amount
const byBooks = (order) => order.type === "books"
const getAmount = (order) => order.amount
```
The objective of this problem is to find the sum of the amounts that has the type of 'books'.

Note: that this version of compose expects an array of functions. This is different to what you might find in a functional library like Ramda. In Ramda's [compose](https://ramdajs.com/docs/#compose), the functions that you want to compose are just directly used as arguments to the compose function.

```javascript
const sumAmountsForBooks = compose([
  reduce(sumAmount,0),
  map(getAmount),
  filter(byBooks)
])
// reads bottom to top

console.log(sumAmountsForBooks(shoppingCart))
// => 70
```
So, we get the correct result, but let's see how it does with a larger dataset.

## Testing, testing, testing...

```javascript
// generate a test array, quick and dirty
function genTestAry(numElements) {
  let A = [], i=0, prod = ["books", "eletronics", "fashion", "diy", "health"]
  while (i < numElements) {
    A.push({productTitle:'', ['type']: prod[~~(i%5)], amount: 10})
    i++
  }
  return  A
}

// sCart with 100,000 objects.
const sCart = genTestAry(100000)

console.time('sumAmountsForBooks')
console.log("Sum for ", sCart.length, "objects:", sumAmountsForBooks(sCart))
// => Sum for 100000 objects: 200000
console.timeEnd('sumAmountsForBooks')
// reports approx 15 .. 10ms. Not bad for 100,000 items!
// As a bit of perspective; the blink of an eye is approx. 300 .. 400ms.
```
## In summary
As an academic exercise this post has shown that the compose function can be looked at as just a reduction of a list of pure functions. The process of function composition is often likened to joining a set of Lego bricks to build a sum which is greater than its individual parts.

Of course, there is usually "more than one way to skin a cat". The shopping cart code above could be achieved in one pass, like this...

```javascript
const  getTotalAmount = (shoppingCart) =>
  shoppingCart.reduce((acc, obj) =>
  obj.type === 'books'
    ? acc + obj.amount
    : acc
  ,0)

console.time('getTotalAmount')
console.log("Sum for ", sCart.length, "objects", getTotalAmount(sCart))
console.timeEnd('getTotalAmount')
// Yes, reports much faster approx. < 5ms.
```
Yes, this code is shorter and it uses .chaining and there is nothing wrong with that; I love dot chaining, but that would not have given me an opportunity to show how compose can do the job and how JavaScript methods can be decoupled from their parent objects. A big shout out to Joel Thoms for that. But, the upshot is, however you decide what method to use, that's fine. But function composition is another tool in your programmers' toolbox ... and that's a positive note to end on.

I hope that this post will help you to a greater understanding of function composition and that you will be tempted to explore a functional library such as Ramda or Lodash; "battle tested" functions for functional programmers. However, you may just need to compose without pulling in a library, so in vanilla JavaScript, you could just use the following.

```javascript
 const compose = (...fns) => xs => fns.reduceRight((v, f) => f(v), xs)
```

If you are inspired to learn more, then take a peek at TK's [Learning Functional Programming repository](https://github.com/LeandroTk/learning-functional-programming)

Good luck on your fp journey!