Search code examples
node.jslodashramda.js

What is the equivalent of Lodash _.transform in Ramda?


I am trying to learn Ramda and I couldn't find in the documentation its equivalent to Lodash _.transform function:

_.transform([2, 3, 4], function(result, n) {
  result.push(n *= n);
  return n % 2 == 0;
}, []);
// => [4, 9]

Solution

  • No, if I understand that function correctly. Ramda will probably never be interested in this behavior. In fact, often when people try to do something similar with Ramda, they end up frustrated. (Disclaimer: I'm one of Ramda's core contributors.)

    What customcommander pointed to seems to be one feature of _.transform that Ramda does manage to handle -- an early exit. Using reduced makes this possible, but I rarely use this either.

    But the whole point of the function supplied to it (the iteratee in lodash's terms) is to mutate the accumulator object. Its return is ignored unless you send the end the madness signal by returning false. And only its side-effects are actually important.

    Ramda is designed around avoiding mutation. When you fold to a list using Ramda's reduce the strong expectation is that you would use concat rather than push; in other words, you would not mutate the input. Ramda does nothing to enforce this, and there are times to sidestep this expectation for performance reasons, but then you might have to be careful about sharing an accumulator between calls. But Ramda is certainly not likely to make it easier to do so. And any function meant to be used only for its side-effects is an anathema to Ramda. (Please don't remind me of forEach! "A foolish consistency is the hobgoblin of little minds.")

    Note that customcommander's answer did not attempt to mutate the acc value but returned a new one: this is very much idiomatic Ramda.

    Also very different is lodash's willingness to create an initial accumulator if one is not supplied. Ramda does not allow for any optional parameters. They are just different designs.


    An important point is that there is no particular reason to expect that every lodash function has a Ramda equivalent. Ramda was developed independently, aimed at a different style of coding, subject to different constraints, and never designed to be a drop-in replacement. So it's relationship to lodash is very different from lodash's relationship to Underscore.

    That they overlap as much as they do is testament to the fundamental nature of many of the functions both support. Of course there is also a non-negligible feedback loop of people requesting from one library the functions found in the other; but I think that much of the functionality is simply widely needed is far more important.