Currying and composition to build lego like code

With the rise of functional programing and composition patterns in javascript, we are always looking for more granularity in our code.

Here meet two design pattern that plays very well together to build super flexible code:

Currying and composition

Let's first have a look to these pattern.

Currying

In one sentence: splitting a single multiple parameter function into multiple function.

Example

// Initial method
const add = (number, numberToAdd) => number + numberToAdd;

// Transformed method
const add = (numberToAdd) => (number) => number + numberToAdd;  

What's the point of doing that?

It allows us to add more abstraction layer into the code by writing operation generator. This give us more flexible and more declarative code.

Here is an example us usage:

// Direct, classic usage
const value = add(1)(anotherValue);

// Creation of a ready to use operation
const addOne = add(1);

// And finally usage of this operation
const value = addOne(anotherValue);  

We will see later that this can be really powerful combined with other patterns.

Composition

Development pattern that tends to replace heritage pattern. By composing we create a method that combines multiple others.

It's a pattern used by redux to apply all reducers to the global store.

Example:

const increment = (number) => number + 1;  
const double = (number) => number * 2;

const incrementAndDouble = Redux.compose(  
  double,
  increment
);

// Equivalent of
const incrementAndDouble = (number) => double(increment(list));  

Important paradigms is that methods can only have a single argument and should return an value of the same type as this argument. So the definition of such a composition compatible method should be:

function<P>(input: P): P;  

All together now

You may have guess the conclusion. The idea is to use currying to transform methods into composition compatible methods. The final goal being to build a super flexible system with simple code bricks.

Let's combine the two examples:

// Without currying and composition
const add = (number, numberToAdd) => number + numberToAdd;  
const remove = (number, numberToRemove) => number - numberToAdd;

const doSomething = (number) => {  
  const result = add(number, 1);
  return remove(number, 10);
}

// With currying and composition
const add = (numberToAdd) => (number) => number + numberToAdd;  
const remove = (numberToRemove) =>  
  (number) => number - numberToRemove;

const doSomething = Redux.compose(  
  remove(10),
  add(1)
);

And tada! With the combinaison of these two paradigms we will be able to build block like code that can be combined and reused infinitely !