# Creating an ES6ish Compose in Javascript

I actually started this article out intending to discuss a javascript implementation of functional Lenses. But I quickly realized that since I plan to brag about how cool it is that Lenses compose, I’m obviously going to need to both build and explain a nice slice-n-dice version of a standard ** compose** function built with all the ES6 trimmings. So first I needed to write

*this*article.

Now, we could always just use the excellent R.compose or _.flowRight from Ramdajs or lodash v4. But then there would be nothing to explain. And it’s fun to explain things!

Anyhow, I’ve mentioned ** compose** before, and hopefully most functional fans are familiar with it, but here’s a refresher on the basic version:

const compose = (f1, f2) => value => f1( f2(value) );

Basically, we’re just nesting functions inside each other so that when they’re called with a final value, the result explodes outwards through each layer.

For my talk about Lenses, however, I’ll actually need the more flexible *gold-star* version of compose. That is, a ** compose** that’s fully variadic. That is, one that can take an

*arbitrarily*long list of functions and then work right to left (inner to outer) to create a composition of all those functions (i.e. return a new function).

(f1, f2, f3, f4…) => value => f1( f2(f3(f4(value) )));

Since functions can only return a single value, all these functions will be assumed to be unary…except, and here’s a tricky bit, the very FIRST function (the deepest inside). It should be able to *accept* any number of arguments (i.e. it can be any arity, from nullary to variadic), even though it will still return a single result like all the rest of its fellows.

At this point, let’s think about the overall structure of this kick-ass ** compose** function we plan to build. It’ll go something like this:

Let’s ignore the *magic* bit for a second and just focus on how the structure of the arguments can and should work. There are two groups of arguments to deal with: the functions and the actual arguments that kick everything off (and will get passed to the first, innermost function). We’ve used a neat bit of ES6's Arrow function syntax to express that:

*() => () => result;*

Basically, that’s a cleaner version of this verbose mess: *function(){return function(){return result;};}*

So, what about the form of the actual arguments in each step?

In ES5, we probably wouldn’t bother to name ANY of the arguments in the first step: to achieve a varidiac function, we’d be stuck using the ** arguments** keyword to get them all as an array (and we’d have to be careful not to use

**directly, as that’s a performance-killer).**

*arguments*With ES6, as you probably know, we have a much nicer way of dealing with that: ** (…fns)** Which means that we can just reference

**in the body of our functions to get the complete list of arguments.**

*fns*But that’s not quite what we wanted! We wanted the *first* argument used (which is to say, the *last *argument passed into the function) to get special treatment. Maybe there’s a neat way to specify the arguments such that that’s so right off the bat? Maybe…

*(…fns, last_fn)*

Wow, isn’t it cool that ES6 allows us to do that?! Haha, well no. It doesn’t. That actually won’t work. And I’ll bet you know why.

Because that ** …fns** syntax has a name: it’s a

**. Ah. It’s a way at getting at the “rest” of something. So it’d sort of make no sense for it to come first and then any other additional thing to come**

*rest*parameter*after*“the rest.” What we can do instead is

**but that’s**

*(fn, …fns)**also*not what we want. Or is it?

Well, maybe. ** Compose** has a twin. It’s often called

**. It’s just**

*pipe***, but run in reverse, meaning that it’s the first argument passed that is innermost and gets the special treatment (i.e. it can be of any arity, and it’ll get called first). That means that**

*compose***is just the reverse of**

*compose***, which means we could just write**

*pipe***and then define**

*pipe***as a call to**

*compose***with the function list reversed. Lets.**

*pipe*Ok, so that seems like a good setup: we get both ** pipe** and

**for the price of one. Now we just need to figure out what the “magic” is. That is, once we have all the pieces to execute the entire chain (all the functions to nest and all the arguments that set the chain in motion), how is it structured?**

*compose*There are two major possibilities to explore here. We know that we have a list of things that we want to boil down into a single thing. We already discussed this: that sort of operation implies that we want to do a ** reduce**/

**-like operation: run through each item in turn and modify a single, final result (in this case, returning the**

*foldl***nesting of functions as if we’d written it out that way, but without having to). That means that the complete**

*fn(fn(fn(fn())))***would look something like this:**

*pipe*Neat! Note again that by passing in just the first set of arguments, the functions, we’re not actually running the reduce operation yet: we get back a pre-configured function that *will* wrap and run everything… but only once the *next* chunk of arguments is passed in.

But reduce isn’t the only way to emulate that nesting logic. There’s another possibility worth thinking through: recursion. That is, instead of reducing the list of functions to simulate the wrapping, we could just have the pipe function keep calling *itself* until it’s run out of extras.

That is, in this recursive version of ** pipe**, the first function passed in is

*always*called with the final, starting arguments. If there are no more functions (i.e.

**is empty and**

*…fns***is 0), we just return that and we’re done. But if there are more functions, then we instead return the result of calling**

*fns.length***with those remaining functions and then calling THAT with the result of**

*pipe***. Each time through, the**

*fn(…args)***construct splits out the first function for special treatment, and then only the remaining list of functions go on through for the next loop. Eventually,**

*(fn,…fns)***will empty out,**

*…fns***will be 0… and we’ll get our result.**

*fns.length*Really cool. Is this better? Well, this recursion version *looks* like it might be tail-call optimized, though no current browser actually implements proper tail-call optimizations yet. Meanwhile, ** Array.reduce** is probably already pretty darn optimized. And finally, it’s extremely unlikely that you’d ever use

**or**

*compose***on a HUGE array of functions: functional programming generally just uses these constructs to glue together a handful of operations at a time, not the**

*pipe**thousands*of iterations it takes to make one start worrying about performance. So I probably wasted your time just to discuss something I thought was a cool little sidebar.

And actually, I probably did that twice.

Because, honestly, using some extra Array sequencing functions to handle arrays isn’t *that* much of a hardship or overly imperative. And if we’re willing to do it, we can just write ** compose** directly like this, without bothering to create pipe:

Now, hey, pipe is a useful functional tool in its own right, & it was worth thinking through how to create it, but we didn’t *need* to make it. Sorry about that.

Actually, sorry again: I got so wrapped up in complaining about how rest parameters work that I forgot how ** compose** works. It’s all

**-ish**

*f(g(h(x)))***right? So while the**

*,***function there is certainly significant because it’s innermost, and should run first, the**

*h***function there is**

*f**also*really significant because it’s outermost. That is to say, we

*can*write a recursive version of compose using rest parameters: we just have to rethink how the recursion works:

Now it does do exactly what we’d hope: it keeps recursively calling ** compose** with the

*first*function treated differently and popped off the stack each time, running until it’s simply returning the last (rightmost) function. That’s then called with

*initial*set of arguments (it’s the last thing returned before the (…args)) and returns its result out to all the other onion layers wrapping it.

How this actually all works in practice when you’re composing together two functions is relatively obvious:

**compose(f, g)** → is…

**f( compose(g)(…args) )** → **compose(g)** just returns **g**, so…

**f( g(…args) )** → which is the same as **f(g(x)))**!

But when it’s three or more functions, it might be slightly harder to think through how the outer arguments end up getting called by the rightmost function:

**compose(f, g, h)** → is…

**f( compose(g,h)(…args))** → which is…

**f(**→

*(…args2 => g(compose(h)(…args2)))*(…args))**compose(h)**=

**h**

**f(**→ same as

*(…args2 => g( h(…args2)))*(…args))**f(g(h(x)))**!

So, not as readably obvious how it all works, but the point is: it works, and now we can define ** compose** all by itself without any helper functions or having to define, then reverse,

**.**

*pipe**Nice.*

#### Ack, sorry again!

As observant coder Achille Urbain has pointed out, maybe all these gyrations to try and treat the first function (i.e. the last, rightmost) in a special fashion are themselves a complete red-herring. Here’s his take on things:

See that? We’re building up a function, so the reducing function can just return a function each time. And since this is a composition (joining up functions), we can probably ignore the empty case (the oddball case of ** compose()** when there are no functions to join: though if we wanted, we could just default to returning x=>x for that empty case). Since

**Array.**is comfortable with that (simply passing the first item as the accumulator), it works.

*reduce*What I especially like about this formulation is that instead of naming the arguments to the reducing function the traditional ** (acc, x)**, it names them

**which is exactly what we’re up to here: sticking a**

*(f, g)***inside our outer**

*g*

*f*