Search code examples
javascriptfunctional-programmingramda.jscurrying

What's the point of _curry1() in ramda.js?


I am reading right now the source code of Ramda and don't understand the point of _curry1().

function _curry1(fn) {
  return function f1(a) {
    if (arguments.length === 0 || _isPlaceholder(a)) {
      return f1;
    } else {
      return fn.apply(this, arguments);
    }
  };
}

Functions that are curried with this function can be called without arguments.

const inc = (n) => n + 1
const curriedInc = _curry1(inc)

// now it can be called like this
curriedInc(1)   // => 2
curriedInc()(1) // => 2

// but it works only with no arguments provided
const add = (a, b) => a + b
const curriedAdd = _curry1(add)

curriedAdd(1)     // => NaN
curriedAdd(1)(1)  // => TypeError: curriedAdd(...) is not a function
curriedAdd()      // => function f1(a)

Question: It seems to me that you can't chain arguments with this function at all. What are use cases for this function? How different is curriedInc()(1) from inc(1)?


Solution

  • _curry1, _curry2, and _curry3 are performance-boosting tricks that can't be used in the public curry function. Ramda (disclaimer: I'm an author) uses them to perform several tasks, clearly mostly doing the currying, but also checking for placeholders so that we can properly do some partial application. The other magic thing about Ramda's currying is the way that you can apply all, some, or even none of the required arguments, and so long as we're not complete, you get back another function looking for the remaining ones.

    Obviously _curry1 theoretically shouldn't be necessary, but it makes it easier to add this sort of consistency:

    const a = curry ((a, b, c) => ...)
    a (1, 2, 3) == a (1, 2) (3) == a (1) (2, 3) == a (1) (2) (3) == a () () (1, 2) () (3)
    

    Notice that last one. When you call a curried function still looking for arguments with no arguments at all, you get back the same function.

    curry1 is what makes that happen; it adds consistency. But that's all it's for.