[HN Gopher] Ramda: A practical functional library for JavaScript...
       ___________________________________________________________________
        
       Ramda: A practical functional library for JavaScript programmers
        
       Author : gravitate
       Score  : 41 points
       Date   : 2023-08-04 17:42 UTC (5 hours ago)
        
 (HTM) web link (ramdajs.com)
 (TXT) w3m dump (ramdajs.com)
        
       | JasonSage wrote:
       | In the late 10s I worked at a startup that was not adopting Flow
       | or TypeScript, and pushing FP using Ramda/lodash-fp seemed like a
       | way to encourage devs to separate out data from dataflow and make
       | things into reusable pieces. Instead of some spaghetti imperative
       | code, we could write a bunch of small functions that work on
       | well-known entities, and compose them up to make a procedure. In
       | theory it was better.
       | 
       | When the company finally came around to using TypeScript, devs
       | could once again reason about code and data and relationships
       | between functions without resorting to abstraction, and the FP
       | stuff died a quick death.
        
         | frfl wrote:
         | It really comes down to finding the right balance and using
         | your tools effectively. I worked at a place at was super OO
         | heavy, multi-layer inheritance, gang-of-4 type OO patterns. And
         | another place that was writing code in a functional manner,
         | little to no classes unless necessary, using FP patterns in the
         | codebase.
         | 
         | Both were codebases were TypeScript. I think I was more
         | effective in the second, FP, codebase than the first. But
         | really it's more about finding the right balance. One of the
         | flaws in either approach is you try to fit a paradigm
         | forcefully: trying to write Java in JS/TS or trying to write
         | Haskell in JS/TS. The TS code will be better if you understand
         | and accept the JS/TS paradigm and apply patterns where they fit
         | elegantly.
        
           | claytongulick wrote:
           | I agree with this.
           | 
           | I don't think it makes sense to be "oop" or "fp".
           | 
           | Different problems have characteristics that lend themselves
           | to different techniques.
           | 
           | Difficult code based come from purists who value theory over
           | practicality.
           | 
           | I have a very strongly enforced "don't be clever" rule for
           | teams I manage.
           | 
           | Code should read like a story, good code reduces congnitive
           | load.
           | 
           | I've seen some chains of map, reduce, filter, etc... written
           | by FP purists that are difficult to decipher.
           | 
           | Good code is a love letter to the next developer.
        
         | SPBS wrote:
         | FP-style castle of abstractions is just as bad as OO-style
         | castle of abstractions. A "function that returns a function
         | that returns a function that returns a..." is just as bad as an
         | "AbstractFactoryManager that manages an AbstractFactory that
         | produces an Abstract thing..." etc.
         | 
         | Don't write code that is so far removed from the actual
         | business data that it becomes hard to reason about cause and
         | effect.
        
           | agentultra wrote:
           | That's called _indirection_ and I agree.
           | 
           |  _Abstraction_ is something else entirely and is usually what
           | you want. Think more like,  "things that have provable laws."
           | Eg: concatenating two lists results in a list that is at
           | least as long as the longest input list, for all lists.
           | Concatenation is the operation on lists that is the
           | abstraction... once you have defined it you no longer have to
           | think in terms of loops and building intermediate lists.
        
             | RussianCow wrote:
             | Abstraction very often leads to indirection, so I don't
             | think "something else entirely" is an accurate description.
        
       | Mindstormy wrote:
       | I view Ramda as a redflag in most any code base I see it in.
       | Anecdotally, every large codebase I have worked with that heavily
       | used Ramda is generally held together by one very smart engineer.
       | Once that engineer leaves the company, the code base falls apart
       | because no one else can understand it very well and it takes ages
       | to fix bugs or ship new features. So these days I champion
       | against Ramda simply because I think it just takes to much effort
       | for a typical engineer to understand and it is usually at odds
       | with the rest of the companies code.
        
         | koolba wrote:
         | What's the alternative for functional transforms in redux
         | selectors?
        
           | woolly wrote:
           | I have used lodash/fp successfully in Javascript projects at
           | current and previous job. Not sure about the TypeScript
           | support.
        
         | frfl wrote:
         | I kind of worked in a place similar to this. But I think having
         | someone who understands engineering as opposed to just
         | functional programming is important. The codebase I worked on
         | was quite functional, written in TypeScript with libraries like
         | fp-ts, io-ts. It did take a while to figure out some of the
         | things, but ultimately I think the engineer who was leading
         | really understood not to go full pure Haskell-in-JS since
         | others on the team weren't hardcore FP programmers.
        
         | 88913527 wrote:
         | How far can this argument be extended? We can go back to
         | vanilla JS/HTML/jQuery; these are all "easy to understand"
         | things. But then too much spaghetti code builds up and then
         | progress grinds down (much like in the Ramda team situation).
         | You need some abstraction and order to maintain consistent
         | productivity levels over the long-term.
        
           | axblount wrote:
           | I don't think they're arguing against abstractions. Just this
           | one in particular.
        
         | dmix wrote:
         | Sounds like you've worked with people abusing Ramda. It's not
         | that complicated when used as a utility library rather than
         | some hard FP approach to programming...
         | 
         | I've been using Ramda for years and I'm really struggling to
         | see how any of the code in our projects have been complicated
         | by it vs lodash or any other similar utility library.
        
       | tekkk wrote:
       | It's a cool library but rarely I get to write something so
       | convoluted in JS/TS that Ramda would make it appear simpler.
       | Rather, it often makes it more convoluted since you can't look
       | directly from the code what a function is doing but have to look
       | up Ramda documentation first. Even that might not help.
        
         | dmix wrote:
         | Utility libraries like Ramda were much more important 5-10yrs
         | ago before ES6+ modernized JS. I find I have to reach for it
         | less and less. But there's a small few I still use it
         | constantly for (union, intersection, any, all, mergeDeepLeft,
         | times, range).
        
       | jauntywundrkind wrote:
       | Ramda putting the options first, data last in the args is a
       | killer move. It means it's easier to bind functions. And many
       | functions can be made variadic, accept all much data as you want
       | to feed, which is a huge boost.
       | 
       | Ramda & fp libraries in general seen to have faded a bit. The
       | utility library everyone knew, lodash, hasn't shipped an update
       | in 2 years. Weird to see this kind of stuff falling away a bit.
        
         | striking wrote:
         | I think it's because with FP libraries you generally end up
         | fighting the language to some extent. That's not universally
         | true, I think https://www.effect.website/docs/why-effect does a
         | good job of harmonizing with JS/TS, but it seems to be the
         | default that FP libraries tend to implement stuff that's very
         | category-theory-forward.
        
         | frfl wrote:
         | Take a look at
         | 
         | - https://github.com/sanctuary-js
         | 
         | - https://github.com/gcanti
         | 
         | I think there's new libraries now rather than the older Ramda
         | and Lodash. The JS ecosystem just seems to move onto newer
         | variants of things over time.
        
           | jauntywundrkind wrote:
           | It was never really my jam, but I used to follow the up-and-
           | coming fantasy-land specs with great interest. It just seemed
           | like a sharp dedicated community of folks trying to figure
           | out better fp & algebraic stuff. I'm not sure who trailed off
           | - in general I feel like there's much less connection in tech
           | world, that the tech twitter and every other ultra-active
           | tech channel has somewhat decayed.
           | https://github.com/fantasyland/fantasy-land
           | 
           | Thanks for the links. I know I've seen @gcanti's name a
           | thousand times already, but had utterly forgotten fp-ts.
        
       | tengbretson wrote:
       | I've gone pretty deep down this particular FP rabbit hole in JS
       | before. I'm not saying that it shouldn't be in your toolbox, but
       | in my experience currying should not be something you regularly
       | reach for.
        
         | toastal wrote:
         | Agree & disagree. What you need is a language where all of
         | these features are first class, piping/compose operators, etc.
         | but without this, the code base becomes unidiomatic, hard to
         | read, and difficult for coworkers to understand. Forcing it
         | into JS is where you have a bad time - there are many options
         | for functional languages that compile to JS tho.
        
           | RussianCow wrote:
           | > there are many options for functional languages that
           | compile to JS
           | 
           | Arguably, depending on what you're building, the pain of
           | integrating an entirely different language into your stack is
           | greater than the pain of simply using something like Ramda
           | (or, better yet, just writing simple, imperative code). YMMV
           | of course--if the problems you're solving lend themselves
           | naturally to purely functional code, maybe something like
           | Rescript or PureScript may be worth it, but for most
           | projects, I'd guess probably not.
        
             | scns wrote:
             | Rescript compiles to really efficient JS. Learning React
             | with ReasonML (Rescripts predecessor) spoiled me, in a bad
             | way. Waiting for TS to compile was really painfull. In
             | Reason it took fractions of a second.
        
       | SirensOfTitan wrote:
       | I considered Ramda at my last company for a hot minute, but
       | ultimately decided it was too opaque to be a reasonable decision.
       | We ended up using lodash for a little while, but in reality used
       | like 2% of lodash, so I ripped it entirely out in favor of our
       | own small utility collection with really sound typescript typing.
       | 
       | I think, in any project, it's best to repeat yourself more, and
       | patiently watch to see which abstractions actually emerge.
        
       | rpowers wrote:
       | I used Ramda for 3+ years. I like somethings but overall wouldn't
       | pick it up again. FP in general makes it really easy for people
       | to write inefficient passes over data. In addition, debugging or
       | code reviewing ramdajs code can be painful as you often have
       | several layers of call stack with meaningless (curryN, pipe, map,
       | pick) functions. I say meaningless because when your whole app
       | uses ramda, you find it very difficult to know what is being
       | map'd or curry'd.
        
         | kian wrote:
         | This is why I prefer a self-optimizing collections library.
         | Many of these inefficient passes can be internally re-wired
         | when combining 'objects' which represent the functions and
         | their rules of composition.
         | 
         | Inline 'debug' pipeline functions are helpful for the second
         | problem you mentioned.
        
       | smrtinsert wrote:
       | Long time ago we already had a large lodash codebase, but I
       | remember liking ramdas api design more. Did a few pocs but we
       | never needed it. We did need a lot of fp though. We were on es6
       | and constantly merging observables. Lodash was a good supporting
       | library for that, but I think the Ramda version would have been a
       | little cleaner.
        
       | solardev wrote:
       | Ramda was a hellhole I hope never to use again. We spent a year
       | trying to learn it, finding it unreadable every time we went back
       | to it (originally added by an outside contractor). Eventually we
       | decided to give up, ripped it all out in a week and went back to
       | lodash and never had an issue again.
       | 
       | Ramda code was just impossible to read and made every 5-min job
       | take hours or days... not worth it, no matter the ideology.
        
         | rudolph9 wrote:
         | I have the complete opposite experience. Ramda is so much more
         | consistent than lodash/fp.
         | 
         | I think your issue has more to due with functional programming
         | in general than rambda vs lodash. It's not for everyone but
         | personally I really enjoy it.
        
       ___________________________________________________________________
       (page generated 2023-08-04 23:01 UTC)