[Arrow function syntax] Move Arrow to head to fixArrowFormalParameters issues

François REMY fremycompany_pub at yahoo.fr
Wed Jun 1 09:17:02 PDT 2011


It seems you're rethrowing the -> vs the @ syntax debate. (replace -> by @ 
in your proposal, you'll get the initial proposal I did)

    setTimeout(@alert('2s elapsed'), 2000);
    setTimeout(@@this.performAction(), 5000);

    function getReference() { return @@this; }

    var props = objs.map(@(x) x.property);

    // possible additionnal shorthand for simple cases:
    // var props = objs.map(@.property);
    // var getValues = objs.map(@.getValue());


The syntax would be exactly the same as you did propose :

    ShortFunctionSymbol FormalParametersOpt InitialValue
    ShortFunctionSymbol FormalParametersOpt BlockOpt

It seems easier to parse since the current arrows syntax makes it impossible 
for the parser to know which kind of object he faces until very late in the 
stream :

    return (x) -> x.property;
    // until the ">" character, the stream could be a valid statement like 
"return (x)-1";
    // the parser may need to restart analysis when he encounters the ">" 
symbol
    // the situtation is worse when there's more than one parameter since 
the comma operator exists in ES5.

The @-syntax has the huge advantage of making the parser immediately 
confident of what kind of object he's going to parse.

I don't understand why nobody has taken this into consideration as of now.

Best regards,
François



-----Message d'origine----- 
From: Sean Eagan
Sent: Wednesday, June 01, 2011 5:30 PM
To: es-discuss
Subject: [Arrow function syntax] Move Arrow to head to 
fixArrowFormalParameters issues

Why not just move Arrow to the head to avoid any current or future
ArrowFormalParameters parsing issues such as the GLR issue ?


ArrowFunctionExpression :
    Arrow ArrowFormalParametersOpt InitialValue
    Arrow ArrowFormalParametersOpt BlockOpt


This would deviate from C# and Coffeescript tradition, but I think
even for people familiar with those languages it would be an easy
transition.  They could potentially be called "arrowhead" functions as
a mnemonic device for the arrow position if necessary.

Here's what the examples from the arrow function syntax strawman [1]
would then look like:

// Empty arrow function is minimal-length
let empty = ->;

// Expression bodies needs no parentheses or braces
let identity = -> (x) x;

// Fix: object initialiser need not be parenthesized, see Grammar Changes
let key_maker = -> (val) {key: val};

// Nullary arrow function starts with arrow (cannot begin statement)
let nullary = -> preamble + ': ' + body;

// No need for parens even for lower-precedence expression body
let square = -> (x) x * x;

// Statement body needs braces, must use 'return' explicitly if not void
let oddArray = [];
array.forEach( -> (v, i) { if (i & 1) oddArray[i >>> 1] = v; });

// Use # to freeze and join to nearest relevant closure
function return_pure() {
  return # -> (a) a * a;
}

let p = return_pure(),
    q = return_pure();
assert(p === q);

function check_frozen(o) {
  try {
    o.x = "expando";
    assert(! "reached");
  } catch (e) {
    // e is something like "TypeError: o is not extensible"
    assert(e.name == "TypeError");
  }
}

check_frozen(p);

function partial_mul(a) {
  return # -> (b) a * b;
}

let x = partial_mul(3),
    y = partial_mul(4),
    z = partial_mul(3);

assert(x !== y);
assert(x !== z);
assert(y !== z);

check_frozen(x);
check_frozen(y);
check_frozen(z);

// Use ''=>'' (fat arrow) for lexical ''this'', as in CoffeeScript
// ("fat" is apt because this form costs more than ''->'')
const obj = {
  method: function () {
    return => this;
  }
};
assert(obj.method()() === obj);

// And *only* lexical ''this'' for => functions
let fake = {steal: obj.method()};
assert(fake.steal() === obj);

// But ''function'' still has dynamic ''this''
let real = {borrow: obj.method};
assert(real.borrow()() === real);

// Recap:
//  use ''->'' instead of ''function'' for lighter syntax
//  use ''=>'' instead of calling bind or writing a closure
const obj2 = {
  method: -> () (=> this)
};
assert(obj2.method()() === obj2);

let fake2 = {steal: obj2.method()};
assert(fake2.steal() === obj2);

let real2 = {borrow: obj2.method};
assert(real2.method()() === real2);

// An explicit ''this'' parameter can have an initializer
// Semantics are as in the "parameter default values" Harmony proposal
const self = {c: 0};
const self_bound = -> (this = self, a, b) {
  this.c = a * b;
};
self_bound(2, 3);
assert(self.c === 6);

const other = {c: "not set"};
self_bound.call(other, 4, 5);
assert(other.c === "not set");
assert(self.c === 20);

// A special form based on the default operator proposal
const self_default_bound = -> (this ??= self, a, b) {
  this.c = a * b;
}
self_default_bound(6, 7);
assert(self.c === 42);

self_default_bound.call(other, 8, 9);
assert(other.c === 72);
assert(self.c === 42);

// ''=>'' is short for ''->'' with an explicit ''this'' parameter
function outer() {
  const bound    = => () this;
  const bound2   = -> (this = this) this; // initializer has outer
''this'' in scope
  const unbound  = -> () this;
  const unbound2 = -> (this) this;

  return [bound, bound2, unbound, unbound2];
}

const t = {},
      u = {};

const v = outer.call(t);

assert(v[0]() === t);
assert(v[1]() === t);
assert(v[2]() === t);
assert(v[3]() === t);

assert(v[0].call(u) === t);
assert(v[1].call(u) === t);
assert(v[2].call(u) === u);
assert(v[3].call(u) === u);

// Object intialiser shorthand: "method" = function-valued property
with dynamic ''this''
const obj = {
  method -> () {
    return => this;
  }
};

// Name binding forms hoist to body (var) or block (let, const) top
var -> warmer(a) {...};
let -> warm(b) {...};
const -> colder(c) {...};
const # -> coldest(d) {...};


Also, why not allow the explicit this parameter with current function
syntax as well via:

ArrowFunctionExpression :
    Arrow FormalParametersOpt InitialValue
    Arrow FormalParametersOpt BlockOpt

FunctionDeclaration :
    function Identifier FormalParameters { FunctionBody }

FunctionExpression :
    function IdentifierOpt FormalParameters { FunctionBody }

FormalParameters :
    ( FormalParameterListOpt )

FormalParameterList : ...
    this InitialiserOpt
    this InitialiserOpt , FormalParameterList


[1] http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax


Thanks,
Sean Eagan
_______________________________________________
es-discuss mailing list
es-discuss at mozilla.org
https://mail.mozilla.org/listinfo/es-discuss 



More information about the es-discuss mailing list