News for hackers. Stuff that matters.
Re:How to use array reduce for more than just numbers by bendiksolheim on Sunday June 02, 2019 @03:29PM (#20077477)
There are tons of wrongs with mutating arguments. The fact that it is possible to mutate arguments in JavaScript does not make it a good idea. Such functions cannot be trusted (how can you know what happens when you call it?), and they are hard to test.

There is _always_ a better alternative to mutating arguments in a function.

Re:How to use array reduce for more than just numbers by nitely on Sunday June 02, 2019 @06:07PM (#20078610)
Sure, but here it's a local mutation, it won't leak to the rest of the program. There is nothing wrong with mutating acc in reduce.
Re:How to use array reduce for more than just numbers by tekkk on Sunday June 02, 2019 @06:59PM (#20078948)
I agree, should you always test the reducing function separately outside the reduce? And if so, what's the real benefit of not mutating accumulator? Seems silly to just copy a transient value which is immediately discarded and then do it for all reduced elements. Does the original reference to the object even stay during the iterations? Hmm, I guess it does.

To me it seems weird to be so puristic about a simple reduce-function, which by-design leads you to mutate the accumulator. I mean for object-accumulators it definitely is just a massive waste to not to just mutate the argument directly without copying. Although as a disclaimer I have to say I am big fan of simple code, were it FP or not. So if you have a messy reduce-function I guess having it immutable makes it a somewhat easier to manage.

Re:How to use array reduce for more than just numbers by modarts on Sunday June 02, 2019 @07:00PM (#20078960)
This is a different argument than what megous was making (JS's support for mutating arguments validating that it's a good practice in a broad sense)

"Unobservable" or local mutation is completely fine (and pretty common in most functional programs that get to any significant scale)

Re:How to use array reduce for more than just numbers by megous on Sunday June 02, 2019 @07:32PM (#20079146)
> There are tons of wrongs with mutating arguments. The fact that it is possible to mutate arguments in JavaScript does not make it a good idea. Such functions cannot be trusted (how can you know what happens when you call it?), and they are hard to test.

I know what happens by reading the function. Pretty much any function that calls a method on some object mutates its argument. It makes little difference if you abstract this mutation behind the method, or do it directly, or do it via a helper function that takes the object as an argument.

> There is _always_ a better alternative to mutating arguments in a function.

No. Most of those are usually more wasteful, because if you can't mutate objects, you'll have to throw them away at every mutation.

Pretty much all issues I ever had with mutation was when object was shared between multiple users, and some users were incorrectly muttating it during some operation that was meant to be temporary.

For example you store params for a AJAX call in some object and for some AJAX calls you just want to modify one of the params for some AJAX call and instead of {...params, prop: 'newval'} you just do params.newval.

But that is a mistake you do a few times, and then learn to recognize when you're doing temporary changes to use copies of objects. Anyway, it is harmful to avoid mutation at all costs.

Re:How to use array reduce for more than just numbers by bendiksolheim on Monday June 03, 2019 @03:15AM (#20081071)
> I know what happens by reading the function. Pretty much any function that calls a method on some object mutates its argument. It makes little difference if you abstract this mutation behind the method, or do it directly, or do it via a helper function that takes the object as an argument.

Are we talking about functions in general, or small accumulator functions here? I would argue that mutating arguments in general is a really bad pattern that certainly will lead to weird and subtle bugs in the long run. It is also completely unnecessary – you have inputs and outputs for a reason. You might know what happens if you read the function yourself, but you can never assume that everyone else will.

> No. Most of those are usually more wasteful, because if you can't mutate objects, you'll have to throw them away at every mutation.

No, you don’t. This is an implementation detail. Libraries like immutable.js [1] (and several others, I believe) makes it possible to work with immutable data structures without cloning anything.

> Anyway, it is harmful to avoid mutation at all costs.

We can more or less agree on this one :) My comment was unnecessary bastant. I have used mutations in reducer aggregators myself. But, avoiding mutation removes a source of bugs, without sacrificing readability or functionality.

[1] https://immutable-js.github.io/immutable-js/

Re:How to use array reduce for more than just numbers by fiddlerwoaroof on Sunday June 02, 2019 @09:20PM (#20079681)
I prefer to limit mutation to changing what a local variable refers to: mutations that escape into the calling context can create all sorts of really nasty headaches.
Re:How to use array reduce for more than just numbers by pkilgore on Monday June 03, 2019 @07:20AM (#20082039)
> There are tons of wrongs with mutating arguments.

What leads you to this dogma?

Why is mutation of a tightly scoped local variable bad?

The initial accumulator of a reducer usually does not exist until the reducer is invoked, or is defined as an arg to the reducer.

What possible harm could result from mutating it in a tight loop until it is returned?

This is not to say that mutation is fine in all circumstances. That's crazy. There are tradeoffs.

But to declare an entire technique off limits, what are your reasons? You seem to assume your own conclusion.

Re:How to use array reduce for more than just numbers by minitech on Sunday June 02, 2019 @08:14PM (#20079369)
> how can you know what happens when you call it?

Documentation, good API design. Real-world example of a function I call pretty often (which I’m also interested in knowing your better alternative to):

  const extend = (dest, from) => {
      for (const x of from) {
          dest.push(x);
      }
  };
It doesn’t return anything, so I’d say it’s pretty clear its entire purpose is to mutate one argument.

(Non-stack-overflowing version of dest.push(...x), by the way.)

Re:How to use array reduce for more than just numbers by fiddlerwoaroof on Sunday June 02, 2019 @09:18PM (#20079667)
I just came across a test that passed spuriously because it passed an object to a function that mutated one of its arguments and then used that object in the assertions.