Reduce context parameter

# Peter van der Zee (13 years ago)

Mostly out of curiosity; why do Array#reduce and reduceRight have no context parameter?

# Andrea Giammarchi (13 years ago)

I think to increase confusion with other Array#extras :D

and since we have this specced as it is now, a third parameter for the context could add even more confusion later on <3

I know, I should not have answered that ...

# Rick Waldron (13 years ago)

I know this doesn't answer your question, but Function.prototype.bind makes thisArg obsolete.

Regarding the origin story, there is some discussion here: esdiscuss/2008-June/006431

# Andrea Giammarchi (13 years ago)

Rick you know bind is that slow and it costs on GC if used massively ;-)

I use a lot the second argument in Array#extras and I feel Peter van der Zee here: reduce/Right should have had that too

br

# Rick Waldron (13 years ago)

On Monday, January 7, 2013, Andrea Giammarchi wrote:

Rick you know bind is that slow and it costs on GC if used massively ;-)

This is not my problem, implementors should optimize. bind() would only occur once per method call.

I use a lot the second argument in Array#extras and I feel Peter van der Zee here: reduce/Right should have had that too

The initialVal argument is optional and undefined is valid — how would you decide if what was passed should be initial value or thisArg?

# Brendan Eich (13 years ago)

The impediment that I recall during ES3.1 days was the accumulator parameter to reduce/reduceRight, which wants to come immediately after the callback function. Both are mandatory, whereas |thisValue| ("context", shudder) is optional. So accumulator won.

As for .bind's cost, let's remember Knuth: en.wikipedia.org/wiki/Program_optimization#When_to_optimize.

# Andrea Giammarchi (13 years ago)

thisArg could have been third optional argument leaving current implementation as it is but making thisArg possible, IMHO

lucky me I don't use Array#reduce that much neither I need the thisArg so far so ... OK for me

# Rick Waldron (13 years ago)

On Monday, January 7, 2013, Andrea Giammarchi wrote:

thisArg could have been third optional argument leaving current implementation as it is but making thisArg possible, IMHO

lucky me I don't use Array#reduce that much neither I need the thisArg so far so ... OK for me

Sorry, but no—this would force user code to always provide an initialVal, even when it would prefer to use the first item the array—which is the default when initialVal is omitted.

# Andrea Giammarchi (13 years ago)

not always, only when thisArg is needed ... Array#reduce(cb, initialValue[, thisArg])

if needed, arr.reduce(cb, undefined, obj) does not look that bad, IMHO

again, I m fine with current status ...

# Rick Waldron (13 years ago)

On Monday, January 7, 2013, Andrea Giammarchi wrote:

not always, only when thisArg is needed ... Array#reduce(cb, initialValue[, thisArg])

if needed, arr.reduce(cb, undefined, obj) does not look that bad, IMHO

undefined is a valid initialVal and won't cause reduce to fallback to the first item in the array (I'd that behaviour was desired). Effectively changing this:

var array = [2,3,4];

array.reduce(cb.bind(ctx))

To:

array.reduce(cb, array[0], ctx);

Not worth it. In fact, it's not even clear now what that param is even for...

var

# Andrea Giammarchi (13 years ago)

but this is wrong array.reduce(cb, array[0], ctx);

since index 0 will be looped so first call previous and current will be the same ... right ? That's why I've used undefined but I understand your concern so, as it is right now, there's no way to implement the context in both reduce and reduceRight ... Peter van der Zee use bind :D

# Rick Waldron (13 years ago)

On Monday, January 7, 2013, Andrea Giammarchi wrote:

but this is wrong array.reduce(cb, array[0], ctx);

since index 0 will be looped so first call previous and current will be the same ... right ? That's why I've used undefined but I understand your concern so, as it is right now, there's no way to implement the context in both reduce and reduceRight ... Peter van der Zee use bind :D

Yeah, you'd need to mess it up further array.slice(1).reduce... Even less worth it now

# Brandon Benvie (13 years ago)

This is why I ended up using $$ArgumentCount and $$HasArgument('name') primitive magics. The ES spec's usage of "argument exists" doesn't really line up with the semantics of default params. The semantics of default params are better but it's too late to go back and make explicit undefined's the same as a lack of a parameter for this stuff (I'm sure someone out there uses array.reduce(cb, undefined) and depends on it).

# Peter van der Zee (13 years ago)

On Mon, Jan 7, 2013 at 11:59 PM, Rick Waldron <waldron.rick at gmail.com> wrote:

The initialVal argument is optional and undefined is valid — how would you decide if what was passed should be initial value or thisArg?

I see. Well, ship has sailed. Thanks.

  • peter

...(Could have specced the context parameter to be second, to be ignored if undefined, and the accumulator third.)

# Brandon Benvie (13 years ago)

As I said: 'undefined' and 'not provided' have a complex relationship in the ES spec. The ship has sailed, but the turd is the shiniest turd you've ever seen.