zenparsing / es-abstract-refs

Abstract References Proposal for ECMAScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Operator precedence

zloirock opened this issue · comments

Whose precedence is higher - . or ::?

Currently, in 6to5 and es6next - :::

{q:1,w:2,e:3}::Dict.map(fn)
// Compile to:
Dict[Symbol.referenceGet]({ q: 1, w: 2, e: 3 }).map(fn)
// Throw error:
{q:1,w:2,e:3}::(Dict.map)(fn)

Strawman propose for method extraction use:

var method = obj::obj.foo;

according . must be higher.

...or not?

For this proposal, :: is given the same precedence and associativity as ..

This enables :: to be used for virtual getters and setters in addition to virtual methods. (I'll post an example later.)

Your example {q:1,w:2,e:3}::(Dict.map)(fn) isn't allowed by the grammar, although we could expand the grammar to allow parenthesized expressions to he right of ::.

although we could expand the grammar to allow parenthesized expressions

It would be good.

Then the hypothetical bound method extraction (with an appropriate Function.prototype method) must be:

::foo.bar -> foo::(foo.bar)

That's a good point, and it makes a good argument for explicitly binding the function in Function.prototype[Symbol.referenceGet].

It's extra work for simple call. Not sure, but Symbol.referenceCall or additional argument ("call" flag) for Symbol.referenceGet can get rid of it.

Function.prototype[Symbol.referenceGet] = function(that, call){
  return call ? this : this.bind(that);
}

I keep coming back to the idea that the case for syntactic sugar over function binding is weak.

Concretely, this:

obj::(obj.bar);

is not obviously better than this:

obj.foo.bind(obj);

While the first is more succinct, the second is more explicit - it's more clear what the intention is.

Either way, it's annoying to have to type in "obj" twice. But fortunately, now that we have arrow functions that use case doesn't come up often enough to warrant it's own special syntax.

Arrow functions is not a solution:

(...args) => foo.bar(...args)

foo.bar.bind(foo)

::foo.bar

I like the LiveScript approach - foo~bar, but it's another operator.

Going to close this - #5 already points out the method extraction thing.