Not a fan of "map" and its ilk, make code harder to understand and modify over time.
Not a fan of "map" and its ilk, make code harder to understand and modify over time.
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.
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.
I've been loving all of the push towards more functional style programming lately. It makes code so much more intuitive for me.
It took a while of actually using some FP patterns for a couple of things to sink in. First, that I'd already been using these patterns in an ad-hoc way, I just didn't have the terminology for it, and second was realising just how repetitive these patterns were in my work. A lot of the code I wrote would either iterate over collections to do stuff to the contents / build a modified collection (map), or iterate a collection and determine something about the contents, like does the user have product x in their cart, or something (reduce).
These days I find code more readable when it uses mapping / reduction and other FP patterns, it's not so much that there's less boilerplate (maybe a couple of lines, nothing drastic), but the grammar itself expresses meaning, I don't have to trace through an entire nested loop section to understand the developer's intentions from the outset.
For instance if I see map, I understand they must be producing a collection based on the input. If they're using reduce, they're figuring out some property of the entire collection.
Also (this is a big plus), the developer would have to go out of their way to modify the original collection, which is always a fun source of unexpected functionality when reading through traditional loops; map and reduce avoid this by design as modified collections are produced as output and don't surreptitiously modify the input. Basically by design you end up with fewer mega-loops that cram in updates, computation, and modify the source data in sneaky ways.
Without reading the contents of the mapping and reduction functions, the grammar of this is very clear to me: "newCollection = (collection.reduce({criteria})) ? collection.map({abc}) : collection.map({def})" - I can see that I'm checking the collection for some criteria, then mapping the collection based on one of two criteria. The grammar itself tells me exactly what's going on before I even have to read the contents of the mapping and reducer functions. Sure that can also be accomplished with a couple of loops, but then I'd have to read through the loops to understand exactly what the broader intention is.
Anyway as I said I consider myself a pragmatist rather than an evangelist for any particular methodology. I don't consider myself a FP programmer but I've found some of the concepts useful tools to have around. Like anyone on a wage, time is money and I use whatever gets the result the client wants in the best way from time, budget, and maintainability perspective. But I hope at least the concept seems a bit less pointless / like code golf with the above context?
That's really all there is to it. Functional programming just means some more expressive, higher-level operations at your disposal. Rather than repeating code to initialize, transform, and iterate over state (tasks you spend relatively more time doing homework on in iterative code), you can spend more energy on your problem domain instead.
When you're using a typed language, it's just that: an implementation detail. All that matters is the type you get out, so you can start ignoring all those details and just focus on your program at a higher level, like "first we start with an array of id's, then we map that into an array of employees, then we reduce it into a sum". Much harder to make a mistake compared to "okay, I'm going to maintain a running counter. Then, within a loop, take an id and find the employee, then add the employee's salary to the running sum. After all this I should have a total salary value".
elements.map(toSomethingElse)
Reads like Hemingway to me.