thisArg in Array#find and Array#findIndex

# David Bruant (12 years ago)

I was wondering whether it was any useful to have the thisArg argument in Array#find and Array#findIndex. As of ES6, the language has Function.prototype.bind and arrow functions and I would imagine these to be enough to cover any use case where thisArg would be used.

I know that in the majority of cases I have experienced, there is no need for a specific 'this' at all. In the majority of the remaining cases arrow functions would have been enough. I guess .bind can do the job find for the remaining 0.1% after that...

# Claude Pache (12 years ago)
  • Consistency with every other Array methods that takes a predicate as first argument, and thisArg as second argument (map, filter, every, etc.).

  • You can use Array#find (and Array#filter, Array#every, ...) now (with a polyfill), but you have to wait, say, six years until you can use arrow functions on the web (until non-ES6 browsers are dead). Meanwhile, using "this" as second argument is the most concise and most elegant way to simulate arrow functions.

# David Bruant (12 years ago)

Le 10/07/2013 14:48, Claude Pache a écrit :

Le 10 juil. 2013 à 11:26, David Bruant <bruant.d at gmail.com> a écrit :

Hi,

I was wondering whether it was any useful to have the thisArg argument in Array#find and Array#findIndex. As of ES6, the language has Function.prototype.bind and arrow functions and I would imagine these to be enough to cover any use case where thisArg would be used.

I know that in the majority of cases I have experienced, there is no need for a specific 'this' at all. In the majority of the remaining cases arrow functions would have been enough. I guess .bind can do the job find for the remaining 0.1% after that...

David


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

  • Consistency with every other Array methods that takes a predicate as first argument, and thisArg as second argument (map, filter, every, etc.).

I can't find it anymore, but I read a message from Mike Shaver (I think it was him) saying that these methods have been standardized after SpiderMonkey implementation without other form of rationale. Who needs this particular consistency anyway?

  • You can use Array#find (and Array#filter, Array#every, ...) now (with a polyfill), but you have to wait, say, six years until you can use arrow functions on the web (until non-ES6 browsers are dead).

I've been using arrow functions for the last 2 weeks with TypeScript. True story :-) Note that even if you don't want to use the whole type infrastructure, you can always use TypeScript to get most of ES6 sugar (if the compiler raises type errors, you can ignore them: js files are outputted anyways)

Meanwhile, using "this" as second argument is the most concise and most elegant way to simulate arrow functions. ".bind(this)" is barely less concise. I have no opinion on elegancy in this case.

# Brendan Eich (12 years ago)

David Bruant wrote:

I can't find it anymore, but I read a message from Mike Shaver (I think it was him) saying that these methods have been standardized after SpiderMonkey implementation without other form of rationale. Who needs this particular consistency anyway?

Users generally benefit from this kind of consistency; we hear complaints about reduce/reduceRight.

The perf savings is an allocation, but the cognitive load win seems more important. Telling people to use .bind (polyfilled) involves more typing and thinking.

# K. Gadd (12 years ago)

In addition to the perf savings from not having to allocate (to call bind) not needing to use bind() for cases like .find() can have beneficial effects for JITs as well. It's my understanding that at a recent point in time (maybe even still today?) functions created by bind() had the ability to deoptimize call sites in V8 and Spidermonkey in certain scenarios. If the existing design lets developers use free functions without having to use bind(), that makes it easier for them to end up in the performance sweet spot we know about when it comes to crunching data. The longer they can stay in that sweet spot and still use built-ins like find/findIndex, the better.

# David Bruant (12 years ago)

Le 10/07/2013 19:28, Brendan Eich a écrit :

David Bruant wrote:

I can't find it anymore, but I read a message from Mike Shaver (I think it was him) saying that these methods have been standardized after SpiderMonkey implementation without other form of rationale. Who needs this particular consistency anyway?

Users generally benefit from this kind of consistency; we hear complaints about reduce/reduceRight.

People seem to have survived reduce/reduceRight.

The perf savings is an allocation

Do engines allocate each time when a function expression is used as first argument? If so, .bind doesn't cost more than a function expression.

but the cognitive load win seems more important. Telling people to use .bind (polyfilled) involves more typing and thinking.

I guess... Are reduce/reduceRight acquiring a thisArg, then?

# Brendan Eich (12 years ago)

David Bruant wrote:

Le 10/07/2013 19:28, Brendan Eich a écrit :

David Bruant wrote:

I can't find it anymore, but I read a message from Mike Shaver (I think it was him) saying that these methods have been standardized after SpiderMonkey implementation without other form of rationale. Who needs this particular consistency anyway?

Users generally benefit from this kind of consistency; we hear complaints about reduce/reduceRight. People seem to have survived reduce/reduceRight.

This isn't about "survival" as you yourself pointed out, since bind (polyfillable) is an option. This is about "best API ergonomics/consistency/cognitive-load". Play fair now!

The perf savings is an allocation Do engines allocate each time when a function expression is used as first argument? If so, .bind doesn't cost more than a function expression.

So? My main point was not perf.

but the cognitive load win seems more important. Telling people to use .bind (polyfilled) involves more typing and thinking. I guess... Are reduce/reduceRight acquiring a thisArg, then?

No, it's too late for those two, and thisArg didn't fit consistently in the parameter list anyway, as we have discussed here in the past.

It's not too late for find and findIndex, and they do fit the pattern.

# Axel Rauschmayer (12 years ago)

It's not too late for find and findIndex, and they do fit the pattern.

Is an options object as the last parameter out of the question? For find(), I’d love to have the option to specify a result other than undefined if the value isn’t found. Such a result would be an option, as would be thisValue.

# Brendan Eich (12 years ago)

Axel Rauschmayer wrote:

It's not too late for find and findIndex, and they do fit the pattern.

Is an options object as the last parameter out of the question? For find(), I’d love to have the option to specify a result other than undefined if the value isn’t found. Such a result would be an option, as would be thisValue.

If there's a pigeon-hole problem where thisArg and notFound fight, then maybe -- but there's another object allocation, and we're not really following any existing pattern at this point. Option objects are common but not in built-in APIs, esp. not in the Array generic methods.

# Brendan Eich (12 years ago)

Also, who needs to find undefined? It's a good notFound default value but I go further: it is the only notFound you're gonna need. IOW, YAGNI.

# Claude Pache (12 years ago)

Le 10 juil. 2013 à 19:05, David Bruant <bruant.d at gmail.com> a écrit :

Who needs this particular consistency anyway?

IMO, when designing an API, the right question is not: Why would I be consistent in that particular case?, but: Why would I be inconsistent in that particular case? You didn't give a good reason for breaking consistency.

# Tab Atkins Jr. (12 years ago)

On Wed, Jul 10, 2013 at 3:13 PM, Claude Pache <claude.pache at gmail.com> wrote:

Le 10 juil. 2013 à 19:05, David Bruant <bruant.d at gmail.com> a écrit :

Who needs this particular consistency anyway?

IMO, when designing an API, the right question is not: Why would I be consistent in that particular case?, but: Why would I be inconsistent in that particular case? You didn't give a good reason for breaking consistency.

+1. Anyone who's had to suffer through PHP knows the pain of APIs that didn't care about being consistent. There are sometimes good reasons to not be consistent, but there's always a strong mental-tax reason for maintaining it.