Allen Wirfs-Brock (2013-11-12T18:59:58.000Z)
On Nov 12, 2013, at 9:27 AM, Brendan Eich wrote:
> ...
> We have problems with paren-free heads for if, while, etc. because statement bodies need not be braced in the paren-ful case:
> 
> https://mail.mozilla.org/pipermail/es-discuss/2011-September/016804.html
> 
> I don't see a similar problem here, yet, but it's a possibility. If class body always starts with { and no expression can adjoin a braced form and make a larger expression, we're ok. This prohibition must be kept in all future editions.
> 
> ...
> If your grammar parameterization only prohibits unparenthesized yield at the end of the extends RHS, that may be worth the ugliness in the spec.
> 
> But first let's make sure we aren't going wrong in allowing arbitrary AssignmentExpression after 'extends'. The paren-free gotcha needs another look.
> 

The { is a mandatory part of the class declaration syntax, not part of the class body.  In that regard, it is more like:
    CaseClause :
          'case' Expression ':' StatementList

which has a mandatory delimiter after the Expression, then it is like IfExpression and friends that have an undelimted Statement as their tail.

But the message you referenced above is more about refactoring/editing hazards so lets look at those types of hazards with 'extends' AssignmentExpression

Assume we start with

     class foo extends bar {}

If somebody added an binary operator after 'bar' but forgot to add its right operand

we would have

    class foo extends bar+ {}

The braces would be interpreter as an object literal that was part of the expression.  But the class body braces are still mandatory so  if the next meaningful line starts with anything other than a { we have a syntax error (and one that ASI can't fix).

Assuming the program was syntactically valid before inserting the + the only thing that could be on the next line starting with a { is a Block.

If the following Block was empty it would be interpreter as the class body and the program would parse correctly.  Of course, a runtime error will occur when the extends expression evaluates to a non-function (but perhaps if 'bar' was a value object with operator overloading, the + might evaluate to a function, but it still seems unlikely).

If the following Block looked like this:

   {f(a)  /*ASI here */
    {/*any Valid StatementList */}
   }

the ClassDeclaration would also parses correctly using the following Block as the class body. EG,
   class foo extends bar+ {}
   {f(a)  /*no ASI here in a ClassBody*/
    {/*any Valid StatementList */}
   }

Note that the hazard of this occurring is essentially the same as if somebody inadvertently inserted a '+' after the 'foo()' in:
   foo() /*ASI here */
   {f(a)  /*ASI here */
    {/*any Valid StatementList */}
   }

except the class declaration case still has the runtime check that the 'extends' expression evaluates to a function.

My conclusion from the above is that 'extends' AssignmentExpression, assuming we fix the 'yield' ambiguity, doesn't introduce any editing/refactoring hazards that don't already exist for common ES language constructs and my impression is that those hazards don't appear to be significant issues for developers using the current language.

Allen

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131112/f94b25ec/attachment.html>
domenic at domenicdenicola.com (2013-11-13T17:05:00.456Z)
The { is a mandatory part of the class declaration syntax, not part of the class body.  In that regard, it is more like:

    CaseClause :
          'case' Expression ':' StatementList

which has a mandatory delimiter after the Expression, then it is like IfExpression and friends that have an undelimted Statement as their tail.

But the message you referenced above is more about refactoring/editing hazards so lets look at those types of hazards with 'extends' AssignmentExpression

Assume we start with

     class foo extends bar {}

If somebody added an binary operator after 'bar' but forgot to add its right operand

we would have

    class foo extends bar+ {}

The braces would be interpreter as an object literal that was part of the expression.  But the class body braces are still mandatory so  if the next meaningful line starts with anything other than a { we have a syntax error (and one that ASI can't fix).

Assuming the program was syntactically valid before inserting the + the only thing that could be on the next line starting with a { is a Block.

If the following Block was empty it would be interpreter as the class body and the program would parse correctly.  Of course, a runtime error will occur when the extends expression evaluates to a non-function (but perhaps if 'bar' was a value object with operator overloading, the + might evaluate to a function, but it still seems unlikely).

If the following Block looked like this:

    {f(a)  /*ASI here */
     {/*any Valid StatementList */}
    }

the ClassDeclaration would also parses correctly using the following Block as the class body. EG,

    class foo extends bar+ {}
    {f(a)  /*no ASI here in a ClassBody*/
     {/*any Valid StatementList */}
    }

Note that the hazard of this occurring is essentially the same as if somebody inadvertently inserted a '+' after the 'foo()' in:

    foo() /*ASI here */
    {f(a)  /*ASI here */
     {/*any Valid StatementList */}
    }

except the class declaration case still has the runtime check that the 'extends' expression evaluates to a function.

My conclusion from the above is that 'extends' AssignmentExpression, assuming we fix the 'yield' ambiguity, doesn't introduce any editing/refactoring hazards that don't already exist for common ES language constructs and my impression is that those hazards don't appear to be significant issues for developers using the current language.