I agree, but I think a lot of it is variable name abuse on the accumulator, making it unclear. I've seen a lot of single letter or worse, a coworker who named it "cum" for short which is super not okay
I've worked with developers that were reduce maximalist. During PR reviews, anything that could be rewritten with reduce was flagged. One of the benefits of AI is not having to care as much about things like that.
Totally get it. `reduce` feels like a hammer for every nail; often `map` or `filter` makes intent clearer for others.
Reduce with barriers is essential (and amazingly powerful) in parallel functional programming languages like CUDA Thrust.
Yeah, it usually adds cognitive load for anything beyond basic summation. Simpler to just use a good old `for` loop.
I like it, but I don't use it anywhere near as much as other built-in closures.
I find the two ways that you call it to be a bit annoying (not a showstopper). It just seems a bit "kludgy" to me.
At least in Python, I've found that "reduce" is very rarely needed. Most of the times, "sum" is enough, sometimes with "start" values customized (set it to [] to flatten an array for example). It is both easier to read, faster, and needs no imports. It also works great with list comprehensions - "sum(foo(x) for x in input if x > 5)" is much easier to read than reduce equivalent.
If you are multiplying, you are likely doing heavy math, and you'll be using numpy - which does not need reduce either.
If you are going to return a list of dict, then it's much faster to mutate the results, so using "reduce" will have significant performance implications (unless you want to return input argument, mis-using it as a glorified "for" loop)
And if returning not a list/dict, if you can use "min" or "max" or "any" or "all" or "next" (take the first element), then you should use it - it will be easier to read and faster too.
So what does this leave us for "reduce"? Frankly, not much. I've only seen it in merging immutable status codes, and that was pretty niche usecase to begin with.
(this was all for Python. In other languages without nice list of built-ins reduce might make more sense)
Anywhere that I could use reduce, I instead write a tail recursive function. This is also why I do not and will not ever choose python or javascript voluntarily.
Well yeah, it's the lowest-level array function. All of the others can be written with reduce, but not vice-versa. Of course it's going to be less friendly.
Reduce requires knowing that the sum of zero entities is zero but the multiply of zero entities is one. They forget to throw the correct number and think that reduce() just do not work for them.
Sure, I'm up for some bike-shedding. [0][1] Unless performance demands otherwise, I prefer map+filter because:
1. It's cheaper/faster at communicating intent to humans reading your code. Since a reduce call can do all sorts of interesting things, people need to stare harder to realize "oh, it's just doing a a map and filter together."
2. Things are easier to debug. I can vet the process of transformation (and its intermediate results) and then vet the process of excluding some of those results.
_____
With respect to debugging, a sample form Elixir's REPL where the piping (|>) to the dbg() function reveals the intermediate state:
iex(1)> [5,34,6,2,7,3,1] |>
Enum.map(fn x -> x * x end) |>
Enum.filter(fn x -> x < 10 end) |>
dbg()
[iex:4: (file)]
[5, 34, 6, 2, 7, 3, 1] #=> [5, 34, 6, 2, 7, 3, 1]
|> Enum.map(fn x -> x * x end) #=> [25, 1156, 36, 4, 49, 9, 1]
|> Enum.filter(fn x -> x < 10 end) #=> [4, 9, 1]
[0] https://en.wikipedia.org/wiki/Law_of_trivialityFor can have another set of variables in the header too. You can simulate it more readably even if you need to call the lambda.
I've always like reduce myself, didn't realize others had a negative attitude towards it.
reduce is great - love it.
Most programmers aren't comfortable with higher-order functions, in my experience. Map and filter are special cases that they may have learnt, but other less common cases they don't understand.
Also, in many languages reduce is hobbled by the fact operators aren't functions. I used it Common Lisp all the time, but it's awkward to use in, say, Python as the function you want is so often an operator. It's also more beautiful if the operators are n-ary like in CL, so the result of (reduce #'+ '()) is the same as (+), ie. 0.
reduce with barriers is essential in parallel functional programming. See the CUDA thrust package.
Not really, programmers only educated in traditional imperative programming I would assert.
I had a client call me up and complain about my reduce code because it was hard to read and he couldn't tell what was going on. I broke through to him when I added comments to it that showed a particular data structure going in, and what was coming out. Once the transformation was clear, the apparent complexity was no longer a problem, leaving me to believe that the problem with reduce is almost entirely about legibility.
Reduce always makes me question the performance and order of operations. The most I'll do in Python is like
sum(x[1] for x in args)
which is map + reduce. And that's only if x[1] is a number. That's about it. No equivalent in JS. Whenever some JS code has map, I'm like why, and rewrite it as a loop.This is also assuming we're talking about regular code and not an actual map-reduce framework like Spark.
I like neither of the three and prefer for loops and if statements instead. Yay for shallower stacks!
Alternative theory - reduce is badly named.
combine, accumulate it aggregate would have way more use.
I like it, but don't care for the name. I find it easier to think about in terms of an accumulator.
[dead]
[dead]
you guys still reading and review code with ur eyes and brain?
Reduce introduces state (accumulator), unlike map/filter which normally are used for immutability.
I use both, but do not like reduce at all. It's harder to read, yes. But I see the point of using them all.