arrows and a proposed softCall

Brendan Eich brendan at mozilla.com
Sun Jun 3 08:20:41 PDT 2012


Angus Croll wrote:
> On Jun 2, 2012, at 23:14, Brendan Eich<brendan at mozilla.org>  wrote:
>
>> Angus Croll wrote:
>>> To my mind (2) is the actual problem. To quote Yehuda "the proposed semantics interfere with more intentional uses of `call` and `apply`."
>>   Users of call and apply who need to override |this| have as their contract that any funarg they take has dynamic |this|.
>>
>
> Yes of course, can't argue with that logic, or your earlier explanation of why modern engines can't be expected  to have call/apply modify a hard binding.

Ok.

> But that's exactly why we should be conservative about locking users into hard bindings when their intentions are not clear (clear: 'bind' or no |this| value, unclear: arrow functions). As someone who views call/apply as cornerstones of the language and who's libraries depend on it, an unintended hard binding is a needlessly broken utility. But I repeat myself.

Are you arguing for -> instead of =>, or in addition to =>?

There's nothing particularly "unclear" about a function that doesn't use 
|this| or else binds |this|, vs. a function that uses its dynamic 
|this|. Clarity depends on many things including how well documented or 
commented the code -- especially that contract that we just agreed 
exists -- might be.

So why are arrow functions "unclear"? Asserting that they are doesn't 
prove the point. It seems to me you're assuming too many developers 
won't learn that => means lexical |this|, and that they'll continue not 
to learn.


> *If the intention is to use call/apply purely as an argument passer this can be indicated by a null context argument which would suppress the error

This is an incompatible change if done for any function that ignores the 
|thisArg|:

js> function f() { var self = this; return function () { return 
self.foo; } }
js> var g = f()
js> var o = {m: f, foo: "o.foo"}
js> var h = o.m();
js> var foo = "global foo"
js> g.apply(null)
"global foo"
js> h.apply(null)
"o.foo"
js> g.apply({foo: "new foo"})
"global foo"
js> h.apply({foo: "new foo"})
"o.foo"

Same for ES5 bound functions:

js> function unb() { return this.foo; }
js> var b = unb.bind({foo: "b.foo"})
js> b.apply(null)
"b.foo"
js> b.apply({foo: "new foo"})
"b.foo"

Why should only arrow functions, among all functions that ignore 
|thisArg|, throw when applied with a non-null |thisArg|?

/be


More information about the es-discuss mailing list