This post will explore a few tricks we can use as JavaScript developers to make code more readable and reusable.

What is composition?

One of the most powerful aspects of JavaScript is the ability to use functions as first-class citizens. Since functions can both accept and return other functions, we can "compose" functions to build complexity while retaining readability and reusability.

In computer science, function composition ... is an act or mechanism to combine simple functions to build more complicated ones. - Wikipedia

My use of Wikipedia as a source notwithstanding, this statement should sound familiar to those familiar with class-based programming. Functional composition purports to solve the problem of building complexity in the same manner that inheritance does in class-based programming (and more generally, all object oriented programming).

Composition, at face value, looks quite simple - put two or more functions together, and get back a more complex function which does the same thing that the input functions would have done when run in sequence.

Composition in Action

First, let's take a look at a very simple case in which we compose two functions into one, to do some basic math. Let's lay out the base functions we will compose.

``````function addTwo(x) {
return x + 2;
}
function timesFive(x) {
return x * 5;
}
``````

Simple enough arithmetic. What if we want to `addTwo`, then `timesFive`? We will pass the result of `addTwo` into `timesFive`. There are several ways to accomplish this manually. Here are a few ways we can define an `addTwoThenTimesFive` function:

``````// Storing the intermediate results, twice:
var z = timesFive(y);
return z;
}

// Store only one intermediate:
return timesFive(y);
}

// No intermediates, nested calls:
}
``````

While we have accomplished what we wanted to do, this is not particularly extensible, and we have to keep track of calling order within the function bodies. The code does not seem to lend itself to general reuse anywhere.

Getting more abstract

Can we make the code look any more generic? How about we use `reduce` on the steps `addTwo` and `timesFive` themselves?

``````// Using reduce on the simple function steps themselves:
return steps.reduce(function(intermediate, step) {
return step(intermediate);
}, x);
}
``````

Well, this works too, but may seem like a head scratcher - the code looks more complex! If we look closely, we see that the function passed to `reduce` above is generic - there is no need for this to pertain to math. The code could be doing any number of things, and the only pieces specific to this problem are the function name `addTwoTimesFive` and `[addTwo, timesFive]`.

This tells us that we are getting closer to a general solution, because we have a piece of the code that is usable anywhere - we could just swap out `steps` to be any other functions and rename the function.

Let's pull the function passed to `reduce` out, so the code is clearer:

``````function runStep(intermediate, step) {
return step(intermediate);
}
return steps.reduce(runStep, initialValue);
}
``````

Now, the body of `addTwoThenTimesFive` conveys intent to the reader. It tells me I am going to `reduce` my steps down, using `runStep` in sequence on `initialValue`.

Composition & `pipeline`

While we able to convey intent to the user in the last example, we still have not solved the problem of reusability. I will still need to manually define an `Array` of `steps` within the new, composed function definition.

How can we keep conveying intent, but prevent the need for repeated `reduce` code everywhere? It turns out, anyone that has ever worked with Bash has an excellent model for this - piping.

Let's borrow the notion of piping and build a higher-order function that builds `pipeline` functions for us - that is, functions that are a sequence of steps, as defined by smaller functions. First, we will revisit the last example above, using placeholders for the function name and value of `steps`:

``````// Original
function runStep(intermediate, step) {
return step(intermediate);
}
return steps.reduce(runStep, initialValue)
}

// Using placeholders for use-case-specific pieces:
function runStep(intermediate, step) {
return step(intermediate);
}
function COMPOSED_NAME(initialValue) {
var steps = ARRAY_OF_STEPS;
return steps.reduce(runStep, initialValue);
}
``````

We can clearly see that the pattern will work on any use case, if only we had an easy way to define the `COMPOSED_NAME` and `ARRAY_OF_STEPS`.

We can do this by making a higher-order `pipeline` function that takes comma-delimited steps and returns the function equivalent to `COMPOSED_NAME`.

``````function runStep(intermediate, step) {
return step(intermediate);
}
function pipeline() {
var steps = [].slice.call(arguments, 0);
return function(initialValue) {
return steps.reduce(runStep, initialValue);
};
}
// Using it:
``````

Now that's more like it. All of the code needed to put the two functions together is now abstracted and isolated to `pipeline`. All we have to do to compose functions is call `pipeline` on the functions we want to compose, and store the result in a variable.

More simple use cases

Now that we have the ability to `pipeline` smaller functions into a larger, reusable function, let's see some use cases.

Because we used `var steps = [].slice.call(arguments, 0);`, `pipeline` will work with any number of steps. The following examples both use three smaller steps, but you can use any number of steps, 0-N.

Finding the magnitude of a vector:

``````// building some small functions out
function square(x) { return x * x; }
function squareAll(nums) { return nums.map(square); }
function add(x, y) { return x + y; }

var magnitude = pipeline(squareAll, addAll, Math.sqrt);

magnitude([3, 4]); //=> 5
magnitude([2, 2, 2, 2]); //=> 4
``````

Doing DOM manipulation (uses jQuery). Suppose we want a function to make `.special` elements in a selection of DOM snippets `.active` and `jQuery.prototype.show()` them:

``````function getSpecials(elems) {
return elems.find('.special');
}
function makeActive(elems) {
}
function show(elems) {
return elems.show();
}

var activateShowSpecials = pipeline(
getSpecials,
makeActive,
show
);
var mySelection = jQuery('anytag.anyClass');
activateShowSpecials(mySelection);
//=> Returns the elements, having now performed the steps.
``````

Complex: `pipeline` of `pipeline`s

Since `pipeline` accepts functions and returns functions, we can pass the result of one pipeline into another! This is particularly helpful if there is a complex set of relationships between frequently used functions.

This is often the case when building up a vocabulary of functions operating on a certain kind of data. Let's build up some pieces of a vernacular of functions operating on `Number`s.

Our two most basic math functions:

``````function times(x) {
return function(y) {
return x * y;
};
}

function plus(x) {
return function(y) {
return x + y;
};
}
``````

Building some simple pipes:

``````var addTwoThenDouble = pipeline(add(2), times(2));
var equivalentMath = pipeline(
times(2),
Math.sqrt
);
``````

Putting it all together:

``````// Many ways to go from 33 => 8

// Manually in sequence
times(2)(35); //=> 70
Math.sqrt(64); //=> 8

// Pipelines in sequence:
//   note that I pass result of one into another
minusSixThenRoot(70); //=> 8

// Doing this in one step

// With our pipeline-of-pipelines
muchoMath(33); //=> 8

// With our long single pipeline
equivalentMath(33); //=> 8
``````

Information overload! We can see that a `pipeline`-of-`pipeline`s is the same as making one large `pipeline` with all the same steps. One would use this technique when both the final pipeline and the intermediate pipelines are useful.

Wrapping it up

We now have a way to use higher-order functions to dramatically simplify the construction of many steps into a single step. `pipeline` is an excellent way to build complexity, as seen with the examples here and in the wild, with analogous tools like the Bash `|` command.

Have a pattern like this that you would like to see implemented in JavaScript? Request a walkthrough like this one with a tweet @ayetempleton!

Appendix: `pipeline` implementations

As created in this post:

``````function runStep(val, step) {
return step(val);
}
function pipeline() {
var steps = [].slice.call(arguments, 0);
return function(input) {
return steps.reduce(runStep, input);
};
}
``````

Advanced: Using `Function.prototype.bind` to save space:

``````function runStep(val, step) {
return step(val);
}
function pipeline() {
return [].reduce.bind(arguments, runStep);
}
``````

Single-function, without `runStep`:

``````function pipeline() {
var steps = [].slice.call(arguments, 0);
return function(input) {
return steps.reduce(function(val, step) {
return step(val);
}, input);
};
}
``````

Math-style composition, which executes right-to-left. This is also very similar to the manual compositions nesting syntax. Simply use `reduceRight` instead of `reduce`:

``````function runStep(val, step) {
return step(val);
}
function compose() {
var steps = [].slice.call(arguments, 0);
return function(input) {
return steps.reduceRight(runStep, input);
};
}

// How this differs from pipeline...:
// Manually done
function multi(x) {
return a(b(c(x)));
}
// equivalent compose call:
var multi = compose(a, b, c);
// equivalent pipeline call (note reverse order):
var multi = pipeline(c, b, a);
``````