Curry And Compose (why you should be using something like ramda in your code)

When it comes to functional programming, the main cornerstone is composability, the ability to create new functions only by composing the existing ones. For example, we can use a function that returns true given a certain condition, and then reuse it in combination with a filter function, to select items in an array.

In javascript, though, this may lead to the creation of several functions that look like the following:

var isGreaterThan = function(limit) {
  return function(value) {
    return value > limit;
  };
};

In that example, we have a function that creates another function. The first only binds a configuration value, the limit, and returns the second one, that in fact makes the comparison happen and return a boolean.

This function is in a curried form, that is, a function that always takes one single argument and returns a value, if it needs more arguments to compute the value, it returns another function to take the next argument, until all are passed, and then the final result is computed.

Using ES6’s arrow function syntax, this can be much less verbose:

var isGreaterThan = (limit) => (value) => value > limit;

If not using ES6 yet, one excellent solution is to use a curry making function, like lodash’s _.curry, or ramda’s R.curry. What these functions do is take a multiple arguments function and return a curried version of it;

//Using ramda's curry
var isGreaterThan = R.curry(function(limit, value) {
    return value > limit;
});

Using this last form has the advantage that we can still pass two arguments to it, and it will work:

greaterThan(10)(20); //true
greaterThan(10, 20); //true
var greaterThanTen = greaterThan(10);
greaterThanTen(20); //true

With curried forms, we have something like a factory of functions, we pass configuration data, receive a function to use in our compositions, and then we pass values to it. As the excellent talk by Brian Lonsdorf, Hey Underscore, You’re Doing it Wrong , we need to pass the data last, and the support values first.

Take for example the filter function. In lodash it takes the colletion as the first argument, and then a function to filter it as the second. They’re passing the data first, making it more difficult to compose with other functions, as we can see below:

//Using lodash here. 
//We flip the order of the arguments in the filter
//function, passing the data last, and curry it.
var filter = _.curry(function(fn, collection) {
  return _.filter(collection, fn);
});

Now we have a more composable filter function, and we can combine with greaterThan easy as a breeze.

var onlyPositives = filter(greaterThan(0));
onlyPositives([-1, 4, 2, -5]); // [4, 5]

This is gold! And this is precisely what Ramda does with these base functions like map and filter. The final move is to take advantage of the fact they receive their data last and use a function to compose several functions. Underscore, lodash and ramda have it, and they’re all similar: you pass a lot of functions to it, and it returns a function that will pass the result of one function as arguments to the next, and return the result of the last, all right to left:

//read from bottom to top

//+ getFirstPositivePlusOne :: [Number] => Number
var getFirstPositivePlusOne = R.compose(
  R.add(1),                 // 4
  R.get(0),                 // 3
  filter(greaterThan(0))); // [3, 6]

  getFirstPositive([-2, -1, 3, 6]); // 4

Only by combining data-last curried functions with compose, we can write much more concise and reasonable code, and all with pure functions, and that is precisely what Ramda does, that underscore and lodash are doing wrong. It offers several pieces of behaviour, properly curried, so we can compose this way, which is called point free way. Point free code is code that does not declare “glue” variables, like this:

//lodash way
var onlyPositives = function(data){ //glue variable (data)
  return data.filter(function(item) {  //glue variable (item)
    return greaterThan(0, item);
  });
} 

//pointfree ramda way
var onlyPositivesPF = R.filter(greaterThan(0)); //no glue variables

Even if your code would not be totally point free, by doing this you can remove a LARGE portion of boilerplate code and most of your unnecessary variables, thus producing smaller, more concise code, and also easier to identify flaws and bugs when they show up.

A defense of functional javascript

The dominant programming paradigm for the web currently is the imperative Object Oriented style. People use it in Java, use it in Python and some even risk themselves trying it in Javascript. Many of us have struggled hard to understand several concepts, such as polymorphism, inheritance and method overloading; some also have studied the ways of design patterns and the famous Gang of Four book to learn the advanced techniques for composing together the pieces of the Object Oriented designs we build.

So much effort makes it difficult for us to look at OOP as not being the only available production ready option, and not even the best one. Javascript has an extremely flawed OOP support, besides the flaws of the paradigm itself. Here I expose my recent opinion about the topic, and why I believe we all should be writing functional javascript, not thinking on objects.

First of all, OOP encourages mutability, which is a known source of complexity in medium to large systems. By coupling operations (methods) with their related data (attributes), we create little units of state spread throughout the system. As the codebase grows, it gets more and more difficult to answer a simple question: “what is going on inside the application?”.

By coupling data with actions, we lose the ability to compose behaviour, and instead, go on composing objects. But the problem is that objects are both, behaviour and data, so we end up with a complex state spread in various places as we put together all the building blocks.

Add to the equation the fact that the javascript implementation of object orientation is far less than ideal. It overloads functions to act as both constructors and transformations, differentiate them with the “new” keyword, and have various problems with “this” binding.

Because functions are overloaded that way, whenever we create a function, we also create a context for “this”, based on whether the function is being called as a simple function, a constructor or a method. Things go really wild as we need to mix method/constructor functions with simple ones, and often we need to use a famous idiom, one that people use so much that they don’t feel like they’re doing something strange:

Foo.prototype.bar = function() {
  var self = this; //see how it's AWFUL?
  something.act(function() {
    self.baz();
  });
}

Let’s face it: Javascript is NOT meant to be used in an OOP style. It is a functional language, based on scheme, with a terrible java friendly syntax. It has first class functions (functions are values, like numbers or strings), has higher order functions and support arbitrarily nested closures.

Functional programming, makes you think about your program as compositions of pure functions (functions that only read their arguments and compute a value, with no side effects), providing a better solution for state control and complexity management.

But not everything are flowers, and javascript also has some problems for functional development, specially about immutability. In the javascript world, where there are no immutable data structures, we can use facebook’s Immutable.js, or mori, or even the less robust ES5’s Object.freeze method, and keep structuring our code around pure functions.

To help differentiate the two paradigms, imagine you have the following story in OOP style:

function Cat() {
  this.catchedMouse = null;
}
Cat.prototype.catch = function(mouse) {
  this.catchedMouse = mouse;
}
Cat.prototype.eat = function() {
  if (this.catchedMouse) {
    this.catchedMouse.die('eaten by a cat'); 
    this.catchedMouse = null;
  }
  else {
    throw new Error('Cannot eat without a catch');
  }
}

function Mouse() {
  this.isAlive = true;
  this.deathCause = null;
}
Mouse.prototype.die = function(cause) {
  this.isAlive = false;
  this.deathCause = cause;
}

var tom = new Cat();
var jerry = new Mouse();
tom.catch(jerry);
tom.eat();

Here we have a cat eating a mouse, modeled as two “classes” (yes, I know javascript does not REALLY have classes, but for some reason people want so much to believe it has that we even got a syntax sugar for that in ES6). First we instantiate the cat and mouse objects, put a state inside the cat object: the catched mouse; Then, when we invoke the method eat, we recover that same mouse and alter it’s internal state.

Now, look at the same story, told in a functional way:

//no constructor function
//we only return a data structure representing a cat
var makeCat = function() {
  return {eaten: []};
};

//we represent state change by returning another
//structure, with the altered content
//without mutating the original inputs
var capture = function(mouse){ 
  return function(cat) {
    return {eaten: cat.eaten, capture: mouse};
  };
};

var makeMouse = function() {
  return {dead: false};
};

var kill = function(causeOfDeath, victim) {
  return {
    dead: true, 
    causeOfDeath: (victim.causeOfDeath || causeOfDeath)};
};

var eat = function(catWithCatch) {
  var eaten = catWithCatch.eaten || [];
  if (catWithCatch.capture) {
    return {
      capture: null,
      eaten: eaten.concat(kill('eaten by a cat', catWithCatch.capture))
    };
  }
  else {
    return new Error('need a captured mouse to eat');
  }
};

var tom = makeCat();
var jerry = makeMouse();

eat(
  capture(jerry)(
    tom));

Here we have modeled the story around the actions, using functions. There is a catch function, a kill function and an eat function. All of them only creates data representing the state of the computation as the result, there is no variable mutation at all.

Also, as all functions are pure, we can reuse them, say, if we need to model a wolf eating that poor cat. Note that all the times we returned a data structure based on another, we can go very performant (and less verbose) using a library of immutable data, like the ones I mentioned earlier.

If we can isolate the change, control the computation as purely as possible, and organize our code as a flow of transformations on data, instead of a mix of mutations on variables; we can reason about the code much easily, and pleasantly; we can reuse more code than we usually could with OOP and finally, we can be much more confident about our craft.