A Ramda-like curry function
Note: this article assumes that you know what is currying and partial application. If that’s not the case you can check http://2ality.com/2011/09/currying-vs-part-eval.html.
Ramda is a functional library. One of its nicest features is that every function is currified out of the box. Underneath, Ramda uses a powerful curry function. Params don’t need to be provided one by one and a special placeholder can be used to specify gaps, allowing partial application of any combination of arguments.
Curry without Ramda
In a recent project we needed to currify some functions but we didn’t want to depend on the Ramda library just for that. We also didn’t need the ability to use placeholders. So, we decided to code our own curry
.
There are many implementations of curry
functions in the wild. Most of them use either EcmaScript 5 syntax or abuse bind
. For our use case we wrote a simple ES2015 version using Function.length and rest params.
Going the TDD route we start by defining some simple tests and support partial application.
Given a fn
function, curry
returns a new function with rest params. It checks fn
’s arity and the number of params received (fn.length
and args.length
). If it can provide all fn
arguments, it does so. Otherwise, returns a new function that partially applies the params.
To code the full curry
version we add some more tests and change the code. Instead of just returning a partially applied function, we return the currified version.
Unfortunately this is not going to work. The inner function length
will always be 0. Rest parameters don’t add to the arity of a function. We can overcome this problem by manually setting the desired arity. We use an inner function curryN
to do it.
Summing up
Ramda is cool. Using it helps us make our code more functional and expressive. However, it’s not always a good idea to couple our code to a third party dependency if we can solve the problem with a few lines of code (or have we forgotten how to program?).