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

Reply via email to