Achieving point-free JavaScript with R.converge / _.over
This story was also posted on my personal blog.
The context
I’m working on a side-project which is mainly a playground for me to practice a more functional approach to JavaScript. There I’m mostly playing with ES6, Cycle.js and Ramda.
Along this journey, I’m doing my best to practice point-free style programming, aka tacit programming, when relevant.
To put it in a nutshell: it means that you never have to say your data. When used wisely, it can help keeping your code clear and concise, avoiding unnecessary intermediate variable declarations. See for yourself:
Then, I found myself stuck in a situation that may sound familiar if you ever tried to achieve that.
The problem
I’ve got a `daysSpent` function that takes a Date, another Date and then return the Number of days spent between those.
daysSpent : Date -> Date -> Number
Then, I have a list of items, each of which having a date attribute:
What I want is to calculate the number of days spent between the first item of the list and the last one − which is something that will be called Lead Time in my context.
Well, I’m almost there. What I need is probably to use the `daysSpent` function. However, the format doesn’t quite match. I guess the naive attempt to do so, using Ramda, would look like:
It sures work, but… something feel weird here.
I’m doomed to declare `items` and spread it around because I need to parse it into different ways before I can process it. I can’t make `items` flow nicely since I need to branch it to respect the arity of `daysSpent`.
This used to be a common issue… which Ramda solves!
R.converge to the rescue
Here is the thing:
Among Ramda toolset, there is a function for that: R.converge. Syntax is the following:
const getX = R.converge( getY, [ parseA, parseB ] );
Aaaand, there we go:
This will call `daysSpent` with properly expected arguments from input. Needless to declare it with a variable, I focus on operations.
Hence, refactoring got event easier:
`leadTime` pluck input `date`s, then `converge` the `head` and `last` of the list into `daysSpent` to get the result. I found some beauty in such simplicity.
Oh and if you’re much a lodash person − I am, but I always wanted to experiment what Ramda got − lodash-fp is doing a pretty good job too. John-David Dalton suggested another approach to do so:
If you’d like to explore further:
- An article about point-free JavaScript
- Get started with Cycle.js
- The philosophy of Ramda − even though lodash-fp is doing a great practical job today, Ramda plays nicely with FP concepts