DEV Community

Discussion on: What s wrong with Array.reduce ?

Collapse
 
pentacular profile image
pentacular

This isn't a very good use of reduce, in my opinion, in any case.

In almost every case where you have an inlined reduction function, you're better off using a for loop, because it is less complicated.

const valid = [];
const invalid = [];
for (const record of records) {
  if (isValid(record)) {
    valid.push(record);
  } else {
    invalid.push(record);
  }
}

Simple, stupid, and gets the job done.

Your use of reduce just adds extra rubbish in the way, and is really a kind of abuse of a reducer in any case -- you're destructively updating it in-place -- so why not just do that in a more obvious fashion?

However, had you defined a reusable reducer, would have been a bit different.

const categorized = records.reduce(toValidAndInvalid);  

Now it's starting to look much more reasonable.

And let's get over this "in a functional way" nonsense.

array.reduce isn't functional -- it's just an application of procedural abstraction, there's nothing functional about it.

At best you can say that it's procedural code being used in a 'functional style', except that, really you can't say that, because you're not using it in a functional style.

So it's a bit like building a run-way in the jungle in hope that presents will magically drop out of the sky. :)

Collapse
 
vonheikemen profile image
Heiker

array.reduce isn't functional -- it's just an application of procedural abstraction, there's nothing functional about it.

Oh but it is. Have you ever heard about Foldable?

Collapse
 
pentacular profile image
pentacular

If it were, you wouldn't be able to go around pushing things in reducers.

As it is, it's just an example of higher order procedure application.

Thread Thread
 
vonheikemen profile image
Heiker

You did read the thing, right? If you didn't, please don't let the name stop you.

Thread Thread
 
pentacular profile image
pentacular

I read it.

Do you understand the difference between functions and procedures? :)

Thread Thread
 
vonheikemen profile image
Heiker

Function like in the mathematical sense? Sure, I like to think I do.

Collapse
 
functional_js profile image
Functional Javascript

Correct, no function on its own is "functional" programming.
"Functional" is only when a function is useable in a composable manner, meaning it can be composed with other functions to make larger functions.

For example, (and somewhat ironically), the "reduce" in python can be used functionally (it may have to be curried first), but not the "reduce" in JavaScript, because in JavaScript it's not a "free-function", it is bound as a member method of the Object blueprint, Array (essentially a Class). Thus in JavaScript's case, it's reduce "method" is Object Oriented. Also, a function that takes a function as a param doesn't simply make it formally "Functional Programming"

Of course you could make it a functional-programming-usable function by wrapping it in a free-function.

For example...

/**
@func
a functional reduce

@typedef {(acc: *, val: *) => *} reduceCallback
@param {reduceCallback} fn
@param {*} startVal
@return {(a: *[]) => *}
*/
const reduce = (fn, startVal) => a => a.reduce(fn, startVal);

//@tests
const p1 = pipe(
  func1,
  func2,
  reduce((acc, n) => acc += n, 0),
);
p1([1, 2, 3, 4, 5]);
Collapse
 
pentacular profile image
pentacular

Correct, no function on its own is "functional" programming.
"Functional" is only when a function is useable in a composable manner, meaning it can be composed with other functions to make larger functions.

Can you give an example of a function that cannot be composed with other functions to make a larger function?

For example, (and somewhat ironically), the "reduce" in python can be used functionally (it may have to be curried first), but not the "reduce" in JavaScript, because in JavaScript it's not a "free-function", it is bound as a member method of the Object blueprint, Array (essentially a Class). Thus in JavaScript's case, it's reduce "method" is Object Oriented. Also, a function that takes a function as a param doesn't simply make it formally "Functional Programming"

Putting aside the issue of javascript functions being procedures.

reduce isn't bound as a member -- you can use it independent of Array, and you can supply any 'this' you like when you invoke it.

Effectively there is an additional argument, which provides the value of this.

I think perhaps you are trying to understand javascript in C++ terms?

Of course you could make it a functional-programming-usable function by wrapping it in a free-function.

Javascript doesn't have a distinction between member-functions and free-functions.

And even if it did, being associated with a class is not in-and-of-itself relevant to being a function or functional.

For example...
const reduce = (fn, startVal) => a => a.reduce(fn, startVal);

All you're doing here is some syntactic hopscotch -- it's calling array.reduce normally, which should tell you that you haven't changed anything fundamentally.

But it's getting clearer that what you consider to be functional is just one particular kind of procedural composition.

What's significant about functions is that they're time invariant.