chore: ramda-adjunct v2.10.0 release
After some idle time we’re here again with new release of ramda-adjunct — v2.10.0. Don’t worry the library has not been forgotten for last 3 months, we have just been busy in our day jobs. But we’re returning back again in a style ;]
According to npm download statistics the use of the library raised dramatically. We are currently looking at around 700 000 downloads a month and 74 dependent libraries. This number makes ramda-adjunct the most popular extension of ramda.
Pedr Browne who is invaluable core contributor to the library came up with the new logo for the library. I personally think it’s super original and neat. This is what Pedr had to say about it after he created the new logo proposal: “The logo should represent utility and simplicity. I also think my idea incorporate the idea of functions locking together and ramda-adjunct (RA) and ramda (R) locking together”…And I absolutely agree with him on that.
From now on, every release of ramda-adjunct will be accompanied with article like this explaining in detail what is inside the release and describing the practical applications of every new feature.
So what is new in ramda-adjunct v2.10.0 release ?
dropArgs
The idea for this function was conceived when I was doing a code review late at night couple of days ago. I will demonstrate my reasoning on a simple code fragment. If you are familiar with redux-observable this code fragment may seem natural to you. For those not familiar, I’ll explain anyway.
xport const epic = (action$, store) => action$
.ofType(reduxAction1)
.pluck('payload')
.filter(RA.isTrue)
.map(() => reduxAction2());
What this code fragment does is that it executes the pipe when reduxAction1 is intercepted, then the property named payload is plucked from the action. Filter operator checks if the payload of reduxAction1 is True. Then we get into the most important part of this observable pipe: the Map operator. When I saw this code I immediately created a Code Review comment to change the code to Point-Free style.
export const epic = (action$, store) => action$
.ofType(reduxAction1)
.pluck('payload')
.filter(RA.isTrue)
.map(reduxAction2);
It was just obvious for me that changing the implicit closure to point-free style has the same meaning and no additional side effects. But I was wrong. As I discussed with the Engineer that created the Pull Request, I realized that what he did was right, but his intention got lost in an imperative way of solving the problem. When you use point-free style the reduxAction2 will receive the payload (True) of the reduxAction1 as an argument. And that’s not what you want. What you want is to call a reduxAction2 action creator with no arguments at all. This pattern was repeating itself in our codebase, so I started thinking how to solve this problem in a way that the code is declarative and the intention is explicit here.
export const epic = (action$, store) => action$
.ofType(reduxAction1)
.pluck('payload')
.filter(RA.isTrue)
.map(RA.dropArgs(reduxAction2));
dropArgs was born. It’s a HOF (Higher Order Function) that consumes a function and returns another function. When returned function is called with arguments, all these arguments are dropped and the original function is called with no arguments.
Ramda placeholder support
Some time ago during doing random code audit, I realized that some of our functions and basically all of our predicates don’t have support for ramda placeholder. Before this release you couldn’t do the following thing:
const isArray = RA.isArray(R.__);
isArray([]); // => true
Now you can. In this release I managed to fix limited list of our functions but there are much more that needs to support this. This effort will be progressive, due to the amount of functions that needs to support the placeholder. If you need to prioritize because of your specific usecases, fire a comment in this issue and I’ll prioritize our work accordingly.
List of functions with added placeholder support: allEqual, allP, isArray.
Progressively making tests more consistent
This is an ongoing effort. When we started with the ramda-adjunct, we tried to mimic practices used in ramda tests. We found out some time after that mimicking how tests are written was not as smart as we initially thought. Currently we are only interested how ramda tests some concepts, rather than how the tests look like. We designed our own way how to write unit tests and now we’re trying to make our test codebase consistent with it. If you want to give us a hand, don’t hesitate to contact us.
Like always, I end my article with the following axiom: Define your code-base as pure functions and lift them only if needed. And compose, compose, compose…