Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
83
rated 0 times [  89] [ 6]  / answers: 1 / hits: 7682  / 2 Years ago, tue, march 8, 2022, 12:00:00

So I've been researching a little bit about JS frameworks. From what I saw, two of the most popular and modern libraries are Lodash and Ramda (right?).


I saw a similar question regarding Lodash and Underscore. However, I didn't see anything related to Lodash and Ramda. Also I couldn't find any benchmark to be honest.


What are the differences? How about the use cases? Which one is better?


More From » lodash

 Answers
5

Dislaimer: I'm one of the founders and chief maintainers of Ramda, so I'm sure this answer will include some personal bias. I'll try hard not to let it get out of hand.


Overview


As to this part of the question:



Which one is better?



There is no way anyone here can answer that definitively. It depends on your requirements, your history, your programming taste, and a million even more fuzzy factors.


I'm biased in favor of Ramda, of course, but I still won't try to tell you which one is better.


But there are significant overlaps in capability between these two and significant differences in underlying philosophy.


Both are grab-bags of utility function, with little or no cohesion between the functions. That is, they are libraries and not frameworks. They don't at all try to determine how you write or organize your code.


They have a great deal of overlap. Among the 305 current lodash functions and the 261 current Ramda ones, there are 103 with shared names, and almost always, similar purpose. Probably half the remaining functions are found in the other library under different names.


A Brief History


Although there were some experimental functional libraries before it, Underscore was the one that brought many of these concepts to the mainstream of Javascript. It stood alone for a while as the undisputed leader in this space.


But there were problems with its performance. Eventually lodash was created in large part to try to do the same thing with better performance. By creating custom versions of classic functions like map, rather than defaulting to the JS engine's built-in ones, lodash was quickly able to outperform Underscore. But it started as a drop-in replacement for Underscore, and kept that focus for a long while.


The Ramda founders were impressed with the ideas in Reginald Braithwaite's JavaScript Allongé and created Ramda as an educational tool to help turn these ideas into a pragmatic library. They were less focused on performance, and more on a clean API and functional composition, as well as immutable data and side-effect-free coding. Through an odd series of events, it eventually grew quite popular.


These days you don't hear much about Underscore. It's still out there, and still used a fair bit, but you don't hear much buzz. For most users, lodash fills that space well. Ramda grew quickly, but seems to have settled down at about 20 - 25% of the downloads that lodash gets. But all three libraries continue to grow in capability and in usage, with Underscore and Ramda about the same usage, far below lodash.


At one point, lodash created a version that tries to take into account some of Ramda's core concerns. I personally have never used lodash-fp so I can't speak to how successfully it does this.


Philosophy


lodash


Lodash focuses on flexibility and performance. Its focus, as its creator once described, is on



providing quality utility methods to as many devs as possible with a focus on consistency, compatibility, customization, and performance.



While no general-purpose library can ever be quite as fast as custom-written code, lodash gets as close as possible.


And lodash is flexible. I wrote several years ago



Consider lodash's filter: It accepts an array, object, or string for its collection, a function, object, string, or nothing at all for its callback, and an object or nothing at all for its thisArg. You're getting 3 * 4 * 2 = 24 functions in one!



Ramda


Ramda is less concerned with performance, and more with simple and clean API design. The idea for Ramda is that a function should do one thing only, and should have a single clear interface. Ramda's filter function takes a predicate function and an object of a filterable type, and returns another object of that type. (Of course this raises the question of what constitutes a filterable type, but that's for its documentation.)


Ramda's focus is on making it simple to compose functions, to work as though all data is immutable, and to avoid side-effects. It also incorporates other functional programming concerns, such as supplying lenses and working with the algebraic types of the FantasyLand specification.


Key Differences



  • Lodash (ignoring lodash-fp) functions mostly take their data first, followed by those things that work on the data, followed sometimes by optional arguments that change the behavior. Ramda puts the arguments least likely to change first, and those most likely to change last. This means that in data-transformation functions the data is last. And Ramda avoid optional arguments altogether.



  • Ramda curries all its functions, as well as nearly all the functions it returns to you. Lodash has a curry function, but you would need to call it explicitly. This is fairly central to Ramda's ideas on function composition.



  • Lodash focuses on reference-equality. Ramda focuses on value-equality. So while these are similar:


    // lodash
    _.union ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [1, 2, 3, 4, 5, 7, 11]
    _.intersection ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [2, 3, 5]

    // Ramda
    R.union ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [1, 2, 3, 4, 5, 7, 11]
    R.intersection ([1, 2, 3, 4, 5], [2, 3, 5, 7, 11]) //=> [2, 3, 5]

    these act very differently:


    // lodash
    _.union (
    [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}],
    [{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
    )
    //=> [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}, {x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
    _.intersection (
    [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}],
    [{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
    ) //=> []

    // Ramda
    R.union (
    [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}],
    [{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
    )
    //=> [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}, {x: 7}, {x: 11}]
    R.intersection (
    [{x: 1}, {x: 2}, {x: 3}, {x: 4}, {x: 5}],
    [{x: 2}, {x: 3}, {x: 5}, {x: 7}, {x: 11}]
    ) //=> [x: 2}, {x: 3}, {x: 5}]

    This difference is significant. Ramda's design is more closely aligned
    with functional systems, but it comes at a large performance price whenever equality-checking is involved. Lodash is perhaps two orders of magnitude faster than Ramda for such tasks.



  • Ramda is chiefly designed to build functions through composition, in short or long pipelines. Lodash is chiefly designed to work with imperative code. You can use either library for either job, but typical Ramda code might look like


    const myFn = R.pipe (
    R.fn1,
    R.fn2 ('arg1', 'arg2'),
    R.fn3 ('arg3'),
    R.fn4
    )

    where the equivalent lodash code might look like


    const myFn = (x, y) => {
    const var1 = _.fn1 (x, y)
    const var2 = _.fn2 (var1, 'arg1', 'arg2')
    const var3 = _.fn3 (var2, 'arg3')
    return _.fn4 (var3)
    }


  • Lodash's focus on performance means that it will supply many well-optimized functions for tasks. For instance, Lodash has all of these functions: isArguments, isArray, isArrayBuffer, isArrayLike, isArrayLikeObject, isBoolean, isBuffer, isDate, isElement, isEqual, isEqualWith, isError, isFinite, isFunction, isInteger, isLength, isMap, isMatch, isMatchWith, isNaN, isNative, isNull, isNumber, isObject, isObjectLike, isPlainObject, isRegExp, isSafeInteger, isSet, isString, isSymbol, isTypedArray, isUndefined, isWeakMap, isWeakSet.


    Ramda, by contrast expects you to supply more arguments to common functions. It has only is, isEmpty, and isNil. But it's is handles
    nearly all the cases above, either by calling explicitly: is (Array, [1, 2, 3]) or by partially applying to make a reusable function const isArray = is (Array)




Some of these differences presumably vanish with lodash-fp. But I don't get any real sense that lodash-fp is a major part of the landscape. And for lodash proper, we can see that the libraries are quite different.


Performance


The question asked about benchmarks. I know of no comprehensive benchmark suite. Anecdotally, it seems except when the issue of value-equality vs reference-equality is involved, lodash is 10 - 20% faster at most tasks. Ramda is not as hyper-optimized as lodash, but it is written with performance in mind, so long as its other more fundamental criteria are met.


In those cases that do involve value-vs-reference equality, the lodash team can point to much higher speeds, but the Ramda team would probably respond that getting the wrong answer quickly is hardly a win.


Target Audience


Underscore helped bring functional programming tools to Javascript. It is a general-purpose utility library, and was designed for any JS developer who wants to be more productive. Lodash inherited this focus. Both are written with developer ergonomics a central focus.


Ramda has a much more restricted audience. It is for those who want to take not just specific tools from functional programming, but who want to take its more fundamental ideas such as functional purity and data immutability. It is aimed both at JS developers who want to move to a more FP style and at those from FP language who want to use JS in a familiar manner. It is written with simplicity a central focus.


Summary


These libraries overlap a great deal in functionality. But their designs, their underlying philosophies, and their developer experience are quite different.


If you're choosing between them, there is a right answer for you, based on the above, but there is no clear definitive best library for everyone.


And you should also consider whether you need one at all. It's not hard to develop your own list of reusable functions to be included in whatever projects need them. The platform has become much more capable than when these libraries were conceived.


[#290] Saturday, February 26, 2022, 2 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
matteo

Total Points: 81
Total Questions: 100
Total Answers: 96

Location: Honduras
Member since Sat, Jul 24, 2021
3 Years ago
matteo questions
Sun, May 31, 20, 00:00, 4 Years ago
Thu, Mar 12, 20, 00:00, 4 Years ago
Tue, Jan 22, 19, 00:00, 5 Years ago
Wed, Sep 12, 18, 00:00, 6 Years ago
Sun, Jul 29, 18, 00:00, 6 Years ago
;