6 ms·
Ramda: A practical functional library for JavaScript programmers
- tengbretson 3y agoI'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 3y agoAgree & 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 3y ago> 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 3y agoRescript 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.
- sprkv5 3y ago+1 the ReScript compiler is a beast: not only is it fast at generating JS, the JS it generates is optimised for performance[1]. If you are using React, it's better to go for ReScript rather than using Ramda or lodash-fp. 1. https://twitter.com/KrComet/status/1653351666446655488 https://twitter.com/KrComet/status/1653351666446655488
- nine_k 3y agoIntegrating a starkly different language has an upside: you have a clear separation line.
- Supermancho 3y ago> the code base becomes unidiomatic, Idiomatic describes the common practices of the ecosystem, without the features (specifically currying, since it's the only one mentioned). How does a codebase that doesn't use these features become unidiomatic?
- toastal 3y agoIdiomatic JavaScript doesn’t use currying. If you add it to your code base, you are now siloing your project to folks that understand currying which has two problems: 1) hiring Joe Schmo to add/maintain will be harder 2) folks that understand currying will almost certainly be more happy & productive in a language that has currying by default & is idiomatic. For instance, the audience that sees fp-ts as a necessary, useful library to code in a manner they find most appropriate will find JavaScript/TypeScript ergonomics verbose, hard to read, and require someone with functional programming experience (see the verbosity according to their docs of TypeScript+fp-ts vs. PureScript: https://gcanti.github.io/fp-ts/guides/purescript.html https://gcanti.github.io/fp-ts/guides/purescript.html). That audience would be better suited doing compiled option such as the aforementioned PureScript, or js_of_ocaml, ReScript, derw, Idris, GHC.js/whatever the new GHC compiler JS output is, or similar option. These languages will have the idioms of fp-ts without the heavy reliance on singularly library most of the TypeScript community doesn’t understand that bloats their code bases without requiring the safety (someone can just call .value on a Maybe/Option breaking the safety). (This is not a knock against fp-ts which is a marvel in & of itself, but the audience doesn’t line up with the idioms of the average TypeScript project).
- JasonSage 3y agoIn 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.
- SPBS 3y agoFP-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 3y agoThat'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 3y agoAbstraction very often leads to indirection, so I don't think "something else entirely" is an accurate description.
- frfl 3y agoIt 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.
- smrtinsert 3y agoLong 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.
- Mindstormy 3y agoI 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 3y agoWhat’s the alternative for functional transforms in redux selectors?
- woolly 3y agoI have used lodash/fp successfully in Javascript projects at current and previous job. Not sure about the TypeScript support.
- danenania 3y agoI like immer for this kind of thing: https://github.com/immerjs/immer https://github.com/immerjs/immer You can do immutable transformations without getting bogged down in FP abstractions.
- solardev 3y agoIf you use something like redux toolkit query, it already abstracts that for you using Immer internally. You can just write a simple arrow function or use lodash or underscore or whatever pleases you. https://redux-toolkit.js.org/usage/immer-reducers https://redux-toolkit.js.org/usage/immer-reducers
- frfl 3y agoI 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.
- rpowers 3y agoI 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 3y agoThis 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.
- morbicer 3y agoCan you recommend such library? I had fun with Ramda but I experienced some perf hits when doing big pipe/map/reduces on large data structures
- kian 3y agohttps://rubygems.org/gems/raskell https://rubygems.org/gems/raskell does it in ruby. A similar technique would work in JavaScript, but I don't know of any other libraries that have attempted it yet.
- tekkk 3y agoIt'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 3y agoUtility 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 3y agoRamda 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 3y agoI 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 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.
- pzmarzly 3y agoI'm very impressed that they managed to express in Typescript type system what looks like algebraic effects, and that the monadic code shown in the docs doesn't look that bad. But TS was not made with that in mind, so I pity whoever has to debug a type error somewhere deep in the code there (probably because some code returns plain JS object instead of computation of it, or the other way around). I think we need to wait for new languages to appear before we can enjoy effective programming with useful compiler errors. In case you wonder what I mean by "algebraic effects" - your code can make a call to something that may or may not return, is defined based on its environment (was set in some code above in the stack) and may have any side effect. Think "try-catch" but with extra operator to go back to place where exception was thrown and continue from there.
- frfl 3y agoTake a look at - https://github.com/sanctuary-js https://github.com/sanctuary-js - https://github.com/gcanti 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.
- solardev 3y agoRamda 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 3y agoI 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.
- solardev 3y agoI don't mean lodash fp, I mean plain lodash. We just rewrote everything into noob style that was infinitely easier to read and also made the code much more concise. The ramda stuff was buried like four levels of abstraction deep and we were able to replace them usually with one-liners.
- tracerbulletx 3y agoI worked on a team that used it heavily, the lifecycle went like this. I joined the team and found it hard to read and understand, I learned it deeply, it became really easy to understand and made sense and I kind of liked it, the old people on the team who chose it left, I had new hires join my team, I found my self in the position of having to see how it affected their experience onboarding, I realized it was just kind of more trouble than its worth, we removed it later when we had the opportunity.
- SirensOfTitan 3y agoI 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.
- fendy3002 3y ago> 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. Which is lodash already, wonder why your team feels like the needs to make and maintain a new component for that is valid. Furthermore, lodash is somehow optimized for it's purpose, so the custom implementation may be inferior. I never aim for file size but AFAIK lodash support tree shaking which is good enough.
- brodo 3y agoInstead of using a library like Ramda or lowdash, I would suggest using modern standard Javascript functions. These kinds of libraries tend to go everywhere (like sand on Tatooine) and you end up writing some hybrid of ‘normal’ Javascript and some pure functional language. If you want to go functional, use Haskell or Purescript. Don’t bend Javascript into something it is not.
- tomdevqer 3y ago[dead]
- mirekrusin 3y agoI find straight forward, dedicated, precisely typed combinators much more readable and practical to use ie. for iterables (context where it makes a lot of sense) [0] example [1], runtime assertions (through refutations, which are much faster than combinators over assertions) [2], parser combinators for smallish grammars [3] etc. In many cases vanilla/imperative js is more readable and terse, no need to bring functional fanaticism everywhere, just in places where it gives true benefits and in form that can be understood by peers. Functional code can be beautiful and can also be unreadable/undebugable. Same with imperative code. It's great in js/ts you can pick approach where the problem is expressed more naturally and mix those paradigms at will. [0] https://github.com/preludejs/generator https://github.com/preludejs/generator [1] https://observablehq.com/@mirek/project-euler https://observablehq.com/@mirek/project-euler [2] https://github.com/preludejs/refute https://github.com/preludejs/refute [3] https://github.com/preludejs/parser https://github.com/preludejs/parser
- tjasdfw2342 3y agoAs an FP purist. These third party libs for JS are a mistake. stick to stdlib and native lang constructs.
- bionhoward 3y agoHard disagree because Ramda is full of well documented standard native FP constructs. if you must use JS then Ramda can help make the code more correct
- Vanit 3y agoPlease don't use this. I see a lot of engineers, particularly stubborn seniors, who are dabbling in JS want to bring their functional programming gifts from heaven to us lowly JS peasants. In reality it makes the project inscrutable and also makes it might impossible to onboard any JS specialists to the JS project.
- ARussell 3y agoPersonally I just don't think Ramda fits really well with JavaScript's mutable and often object-oriented nature. It goes against the grain too much for my taste, and it doesn't work very well with Typescript. In a professional setting I will probably always reach for Lodash due to it's maturity and mindshare. Personally, though, I really prefer Remeda (https://github.com/remeda/remeda https://github.com/remeda/remeda) as a pragmatic and flexible API.