Angus Croll wrote:
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 =>?
At this point I'd settle for anything that allowed both abbreviated
syntax and late binding via call/apply. That could be any of:
1) Arrow function that shortens syntax but leaves semantics alone
2) Arrow function with soft lexical binding
3) Thin arrow as no-semantic alternative to fat arrow (coffee script
style)
Looks like (3) has the most chance of gaining acceptance - that would
work for me.
(1) has to be -> or we'll get lynched by CoffeeScripters and anyone who
sees the precedent there.
You agreed (2) ain't gonna happen, so let's drop it.
That indeed leaves (3) but it's a hard sell right now. I'll feel out
members of the committee. It could happen, don't get me wrong, but as we
only just got => in via cutting complexity including having two kinds of
arrows to choose from, one of which lands common 40-50% use cases back
in the dynamic |this| trap, trying to re-inject -> will require careful
argumentation.
*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|?
Not suggesting that arrow functions be special cased or that they
ignore |thisArg|. I'm suggesting for all relevant cases (=>, bind and
no |this|) we only throw an error on call/apply if the |thisArg| is
non null.
We can't do that, though:
1. It's backward-incompatible, breaking 1JS with a runtime-only shift in
semantics.
2. It's hard to decide what a function that doesn't use |this| actually
is. Mark proposes a conservative approximation but you'd get false
positives throws. This is arguably ok for an isBound predicate, less so
for apply and call special-casing (ignoring 1).
What's more, I don't see why this matters now given apply and call
dating from '99 and ES3, and functions that don't use |this| (including
the pattern used to implement bind in the language itself) existing all
this time. I haven't heard anyone asking for an error when trying to
pass a non-null first arg to .apply/call on a function that doesn't use
|this|, until now.
There could be a problem that did not rise to anyone's attention till
lately, or possibly it was not diagnosed, merely latent. But is it
possible that this is a non-issue, because people generally satisfy the
|this|-contract of APIs they use, *especially* where the contract
requires dynamic-|this|? Rather it's the other side of the coin, where
lexical-|this| is assumed, that has risen over the years as a pain point
showing dynamic-|this| can be a footgun.
But I agree the coin has two sides. IIRC from talking with @jashkenas,
he couldn't tell which side was heavier by frequency of use, so wanted
two-char arrows. He went for => as "fat arrow" to convey the greater
overhead of a self-hosted bound lexical-|this| function compared to
"thin arrow".
I'm in favor of both and wrote
http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax to
spec both. I'll keep working on ->, but not without arguments that
attend to the ones leading up to ES6 getting => this past March.
/be
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss