12 ms·
FP techniques that will help you write better JavaScript
- deleted 5y ago[deleted]
- thinkingkong 5y agoId highly recommend an older but wildly relevant book called Javascript Alonge. It totally changed the way I wrote JS and understood functional languages for the better.
- heavyset_go 5y agoI haven't actually read the content, but since the site seems to be down, here's an archive: https://web.archive.org/web/20220210073935/https://www.epicprogrammer.com/2022/02/functional-ranges-for-loops-generating.html https://web.archive.org/web/20220210073935/https://www.epicp...
- feupan 5y agoSorry but bad article. It resolves with a “range()” function and then uses for-of to call it: that’s not functional programming. Then every for-of loop example does not execute anything because it’s creating an inline arrow function without calling it.
- eMSF 5y agoWhat I also noticed was one of the problems the author claims that "imperative" style loops have: >Off-by-one bugs are more probable. For example, you might write i<22 instead, and then the loop would end at 21, not 22. Ironically, their implementation of a function called "range" differs from the (likely) best known function by that name (that of Python), causing exactly this problem. (Also, the Pythonic range is probably a better fit for a language with 0-based indexing.)
- graup 5y agoIf anyone needs a typed JS version of Python's range, I prepared this code to be a 1:1 match with the Python API. It also uses generators: https://github.com/graup/pythonic-ts/blob/main/src/iterators/range.ts https://github.com/graup/pythonic-ts/blob/main/src/iterators...
- missed-pos 5y agoOh, I thought this article is about pure functions, immutability...
- bee_rider 5y agoCloser to what you wanted than me, I guess -- was expecting something about floating point computations...
- vippy 5y ago
- yakshaving_jgt 5y agoThe article at least paid lip service to `map` and `reduce`. It's a shame the author spent most of their effort describing `forEach`. This is quite a superficial take on FP. It would be better to guide the reader into a different mental model entirely. What is presented here is essentially a syntax-swap. If you're a JavaScript developer and you want to learn Functional Programming, then learn Elm. It's a small, easy language, and learning it will make you a better JavaScript programmer.
- Rodeoclash 5y agoHmm, I'm not convinced by the article. One of the best tools I found to really dive into functional programming in JavaScript was Lodash's "fp" variant. It will swap the order of the arguments to its functions and curry them all by default. So you're building a function to "add one" const addOne = map(function(n) { return n + 1 }); Can then be applied against an array of numbers: addOne([1, 2 ,3]) > [2, 3, 4] This is fairly basic though. Where it really shines is when you start to use the `flow` function will can be used to compose multiple functions together (and makes the order of execution follow from left to right) flow(addOne, reverse)([1, 2, 3]) > [4, 3, 2] I find this is one of the small redeeming features of JavaScript!
- yakshaving_jgt 5y agoIf I were reviewing someone's code, I would be quite surprised to see this: addOne :: [Int] -> [Int] It's not idiomatic in FP (as far as I'm aware) to bake the structure in like that.
- Rodeoclash 5y agoTrue, the example could be better: const addOne = (n) => { return n + 1} map(addOne)([1, 2, 3]) > [2, 3, 4] Would decompose the addOne into its own standalone function. My only excuse was that I was in a hurry due to Minecraft time with my son.
- onion2k 5y agoI worked on a project that used lodash/fp for a couple of years. It really is game-changing if you have a large object that you need to change in similar ways across different properties. Theres also Ramda (https://ramdajs.com/ https://ramdajs.com/), which I slightly prefer because the documentation is significantly better.
- Rodeoclash 5y agoRambda is an excellent library but I've found difficult to use to teach newcomers to FP concepts. Once you start to get into transducers, lenses (which Lodash has, just calls them something else) then it can be a bit of a bridge too far as a tool to start with. Lodash/FP always seemed to me to strike that nice balance between complexity and getting things done. That said, if I was on a project with a bunch of developers that really grok'd FP concepts then Rambda would be my first pick, absolutely.
- stupidmoron 5y agoI write a lot of JavaScript and have never decided on using .forEach over something else. I have never used it. Nor have I, or will I, use yield / generators, because they are confusing and silly, which is why nobody uses them. I don't believe these things will make you write better JavaScript, but rather, worse JavaScript.
- scrapheap 5y agoThese things are all just tools in the programmer's tool box. Which one you use will come down to the one you think is most suitable at the time based on your knowledge and experience. Generators are very useful in more complex scenarios, but when used in simpler environments they'll just add confusion - in fact the article is a good example of adding confusion with a Generator. Personally, when dealing with arrays I favour using .map, .reduce, .filter and .forEach.
- dan-robertson 5y agoI think forEach was a lot more compelling when for(… of …) wasn’t widely supported
- Waterluvian 5y agoGenerators are fundamentally important to have to solve a number of problems. But like me, you probably never need them because you aren’t solving those problems.
- brundolf 5y agoFP is about avoiding side-effects; forEach() can only cause side-effects, so it's not really functional at all, and yet it's superficially designed to blend in with the actual functional array methods like map(). IMO it's the worst of both worlds and there's virtually never a good reason to use it. If you're going to write a side-effect-y loop, a classic for-loop (or more often, a for..of loop) helps to emphasize that the code is side-effect-y.
- spoils19 5y agoAll most programmers will need is a classic for-loop. For of, forEach and any other kind of iterator is really not necessary and adds to the language bloat that just confuses less experienced developers.
- yakshaving_jgt 5y agoActually, all most programmers need is either `map` or `reduce`. A classic `for` loop is too low-level for most people’s needs.
- Xevi 5y agoI find it really difficult to believe that there are developers out there that never need to be able to break or continue in a loop. What exactly would they be developing?
- yakshaving_jgt 5y agoI’m not sure where you got “never” from in my comment.
- bryanrasmussen 5y agoI believe it was gotten from the ambiguities of English - when you say "all most programmers need is " it could mean all that is needed most of the time but probably the more usual meaning would be that a great number of programmers (most programmers - greater than 50% of programmers), will never need anything but `map` or `reduce`. If the second meaning is taken then this means as a corollary that these developers never need to be able to break or continue in a loop. Of course if it were assumed they never need anything but the higher level methods: map, reduce, some, every etc. - then they would probably use some or every if they wanted to break.
- vore 5y agoUsing forEach/map/etc. can often result in worst performance, because some JavaScript JITs (SpiderMonkey in particular has trouble with this) aren't able to monomorphize calls to them effectively and end up falling back to the interpreter due to the megamorphic nature of these higher-order functions. Even for engines that do, you do end up paying a cost for the JIT to warm up to monomorphize these functions.
- yakshaving_jgt 5y agoOk, but how much? And how does the cost compare against the impact of correctness errors? To just say “there is cost” is not so useful; there is cost to everything.
- koshergweilo 5y agoI used to do js gamedev and really it's only a problem in hot loops. Absolutely fine to use it a lot when doing basic webdev/server work
- vore 5y agoAs always, benchmark and profile! However, from first principles, this is one of the degenerate cases of certain JITs that often catches people off guard, but has a straightforward transformation to avoid the pessimizing behavior – especially if your loops end up looking like they're particularly hot.
- bni 5y agoI use "for.. of .." loop in JavaScript, I think it's the most readable form. Not a fan of "map" and its ilk, make code harder to understand and modify over time.
- abyssin 5y agoIt might be a thing of personal taste, but programming became significantly easier for me when I discovered map and reduce, including editing what I’d previously written.
- throwaway77384 5y agoSame, but I can't shake the feeling that I am missing something, as some people are really insistent that FP is the _only_ way forward. I've had cursory glances at the ideas of FP and find it very difficult to understand (probably due to many years of OOP style imperative programming). Now I wonder whether I should have just started with FP and ignored everything else. Is the idea behind FP that it's just much less likely for your code to be incorrect? Because to me it looks more like the sort of thing code-golfers love, because it allows for cramming even more implied functionality into ever-tighter, ever-harder-to-read spaces. Which, I suppose, is fine if everyone is on the same level, but I'm not sure how I'd apply something like this in a larger organisation / code base. Again, I am speaking from ignorance and openly displaying this ignorance intentionally so that I may be proven wrong. I am inviting this, as I'd like to know more about FP.
- gherkinnn 5y agoFor one, you’re dealing with less state. That’s worth a lot already. More interestingly, programming in a functional style encapsulates a lot of complexity in concepts. Once you grasp a concept, it all falls in to place. But getting there is hard. Java-style OOP gives you a loose bag of conceptually simple pieces, but that quickly devolves in to a horde of rabid infants with jetpacks. Then you need to memorise several dozen patterns to contain the chaos. Intrinsic vs extrinsic complexity.
- bluefirebrand 5y ago
- newshorts 5y agoI mostly end up using map, filter, for in and for of. Occasionally you still need a good “old fashioned” for loop but in my mind it’s more clear to use that then forEach. While loops have their own special powers for recursion so those are still appropriate and not something I would label as “old school” but hell, maybe that makes me old school! I can’t find a ton of good personal examples where I’ve needed a range function. This article feels more like the author was “exploring” techniques rather than proposing a standard practice
- Waterluvian 5y agoJavaScript got very tolerable, even good, almost, after ES6. But I’m still reminded on a weekly basis that it doesn’t have a functional way to do something X times. Which is probably why this article spends so much time implementing that.