logoalt Hacker News

catapartyesterday at 10:09 PM6 repliesview on HN

For me it's the name[0]. map puts out an array that has been mapped from another array. filter puts out an array that is a filter of the input array. both of those are always true. reduce, on the other hand, may put out a reduction of the input array (probably most of the time), but the fact that it may not means that what is happening is not actually a reduction. In languages like js/ts, you don't even have to return anything of the same type as the input array's elements. You could literally "reduce" and array of integers to a cancellation token, or a state object, or anything else.

I realize it's not the most efficient way to work, but I like my code to read like instructions. There's nothing reduce will do that a for loop won't accomplish and the for loop (+ an accumulator, of course) is more clearly "readable" than reduce. If I read map, I know what's going on. If I read filter, I know what's going on. If I read reduce, I have to figure out what's going on, even if I'm pretty sure what is going on. If I could rely on reduce to always give me back an element of the input array, I would use it more. But since it can give back anything, I prefer the simplicity of a for loop.

[0] I don't have any suggestions for "better" names because the whole operation is hard to sum up in a word? "dispatch" makes sense, as a function dispatching a function over each element in an array, but it masks the concept of accumulation from return values. "transform" is accurate, but hardly descriptive at all. the list goes on. It's an undeniably useful little function, it's just hard to make it easy to understand and therefore debug.


Replies

xp84yesterday at 10:20 PM

Ruby adds an alias `inject` for reduce. The #1 way I see it used there is like this:

  some_hash = my_array.inject({}) {|accumulator, item|  ... }
But I honestly very rarely use it (by either name) outside of a couple of pasted-in snippets (that I can't recall right now) where the strategy fits exceptionally well, probably because of the dumb reason that I tend to forget which block argument comes first (accumulator, or iterated item)! With other two-item argument lists such as `Hash#map` it being `key, value` makes sense, but with reduce/inject I don't see an obvious order. And I guess I learned before it was likely that some kind of AI autocomplete would be filling the args in for me.
show 2 replies
layer8today at 1:52 AM

It reduces n items to one item, recursively. The items don’t have to have the same type. Arguably accumulate is a more fitting name. I think of “reduce” as in cooking, boiling a volume of stuff down to some essence.

I also agree that a for loop is often clearer.

adamddev1yesterday at 10:46 PM

I like the name `fold` as used by Haskell, Racket, et al. It gives me an image of folding up a long list into a ball, one chunk at a time.

show 1 reply
mkehrttoday at 4:10 AM

> You could literally "reduce" and array of integers to a cancellation token, or a state object, or anything else

This is what reduce does, though? It reduces a list to a single thing. It seems like you're thinking of filter.

reddit_cloneyesterday at 11:15 PM

There is a big difference in there I think.

'for' loop is mutating.

Using 'reduce', you can do the same functionally. In some (somewhat) purely functional languages, there is no choice.

scotty79yesterday at 10:14 PM

It doesn't have to be exactly correct. It just need to express intuitively the most common use(es?).

Aggregate, accumulate, combine for example.