A few arrow function specification issues

Brendan Eich brendan at mozilla.org
Sat Apr 21 17:10:36 PDT 2012


Angus Croll wrote:
> On Sat, Apr 21, 2012 at 3:06 PM, Axel Rauschmayer <axel at rauschma.de 
> <mailto:axel at rauschma.de>> wrote:
>
>>     On Sat, Apr 21, 2012 at 1:56 PM, Axel Rauschmayer
>>     <axel at rauschma.de <mailto:axel at rauschma.de>> wrote:
>>
>>         Counter-question: Isn’t it clear when you create a function
>>         whether it is going to be a non-method function or a method? 
>>
>>
>>     It's clear to the implementer - Its not clear to a function that
>>     gets it as an argument - unless fn.prototype is checked
>
>     I would argue that – in ES.next – whenever a function is passed as
>     an argument, one should always assume that it is a non-method
>     function and completely ignore `this`.
>
>
> This makes me sad. Seems like functions are going to be a little less 
> first class than they were before

There is no "before". Today, no ES6, you pass to another module written 
by someone else (or by an older and forgotten "you") a function that (a) 
you wrote and (b) uses |this|, you had better .bind(that) or otherwise 
make sure it receives the right |this|.

People fail to do this all the time. The easiest bug is just to use 
|this| in a function expression assuming it will be the same as in the 
enclosing function. Seasoned programmers make this mistake, it's the 
safety-last nature of always-dynamic |this|.

Given the requirement *today* that you bind |this| or don't use it, 
there's nothing less "first class" in the future. The problem exists 
today, and indeed some analyses showed 80-90% or more of functions 
either bind |this| or do not use it. These are all candidates for arrow.

But if we make arrows allow |this| override, then the roughly half of 
that 80-90% that want to bind |this| cannot be sure a caller won't 
override via .apply or .call (why not through a method reference too?). 
We'll be back in the "I forgot to use .bind(that) or var that = this; on 
the outside, the footgun fired all too often.

> - and for fairly arbitrary reasons (the introduction of tight-bound 
> |this| in one syntax varietal).

There's nothing arbitrary about fixing the hazard with new syntax that 
reliably binds |this|. The argument to have is whether -> should be 
added too.

> And not being able to assume call and apply will work on any given 
> function feels like the road to deprecation.

You cannot assume |this| can be overridden by apply and call today:

js> function f(){"use strict"; return this.x}
js> f.apply({x:42})
42
js> g = f.bind({x:99})
function f() {[native code]}
js> g()
99
js> g.apply(101)
99

(No ES6 here, and ES5 not required -- bind preceded ES5 by many years 
and can be written in JS.)

Assuming something not guaranteed is a mistake. The fix is not to keep 
assuming and propagate the assumption (that |this| can be overridden) to 
new and better short-function forms.

/be


More information about the es-discuss mailing list