REQUEST A DEMO

Pointfree Javascript


Pointfree Javascript

In a recent post Functional Javascript, we talked about using functions to simplify our coding practice.  I would like to dig in a bit more and talk about pointfree.  Pointfree is a function that doesn’t know what its data is.  For example:

// Not Pointfree
var initials = function (name) {
  return name.split(' ').map(R.compose(R.toUpper, R.head)).join('. ');
};

//pointfree
var initials = R.compose(R.join('. '), R.map(R.compose(R.toUpper, R.head)), R.split(' '));

Notice our first function takes in a parameter of name, because it knows its data it is not pointfree.  Our second function does the same as the first but doesn’t know its data.  Therefore, it is pointfree.  For some, the second function is foreign and confusing and the first is something closer to what you might be used to seeing.  However, even the first could be confusing, what is compose, how come the functions don’t have parenthesis, and how can this work when the function doesn’t know its data?

Compose

Compose is just a function that takes curried or first class functions as parameters and executes them right to left when invoked.  A first class function is a function passed that isn’t invoked yet.  In our pointfree code example, that code is just sitting there, it hasn’t been invoked.  To invoke it we simply use the function initials

initials("gary cox"); // => G. C

Lets examine what is happening.  Knowing compose is working right to left, which in a functional representation it would look like this

R.join('. ', R.map(R.toUpper(R.head)))(R.split(' ')));

Given we have passed in “gary cox”, the following is happening in this order:

1) R.split is called returning [“gary”, “cox”]

2) R.map is iterating over the array passed and picking off the head (first char) and upper casing it, the return value is [“G”, “C”]

3) R.join is now getting the returned array and joining it with a period and space returning “G. C”

Conclusion

Using pointfree functions gives us the flexibility of reusable code that can be joined with other pointfree functions.  You might have a function that fetches some image urls, join that with a function that builds up image elements, join that with a function that adds styles to image elements.  All of which would be conducted in a compose.

const imageManager = R.compose(styleImages, buildImages, fetchImageUrls);
...
document.querySelector('#image-display').append(imageManager('http://api.images.com?q=cats'));

This of course is just for show but I hope you can see the benefits of these tightly coupled functions that service a specific need.  Keep in mind, not all functions should be pointfree.  Pointfree has its place, when specific functions need to be invoked with an input that outputs specific data.  Composing functions doesn’t mean they are all pointfree, you could curry your functions when they have 2 or more parameters and add them to the compose function as well.  If your function only takes a single param, then no need to curry, simply pass it in as a first class function like we did on the imageManager example above.

 

Checkout this OSS book on pointfree for further reading.

%d bloggers like this: