Unifying Block and ObjectLiteral (was: Re: block-lambda revival)

Brendan Eich brendan at mozilla.com
Tue Jun 28 15:10:47 PDT 2011


On Jun 23, 2011, at 3:27 PM, Brendan Eich wrote:

>> Also, if any { block } could be a lambda, perhaps we won't need that (nor any new) syntax for block-lambdas.
> 
> We would need new syntax still, for formal parameters.
> 
> Making blocks be expressions requires unifying the ObjectLiteral and Block productions. I don't know how to do this in without at least two-token lookeahead, and it is not a backward compatible change if done for all places where Statement : Block in the current grammar.

Apologies for not crediting Breton Slivka, who suggested working this approach here:

https://mail.mozilla.org/pipermail/es-discuss/2011-June/014933.html

Here's an attempt to formalize the unification grammatically.

Block:
    { UnlabeledStatementFirstList }
    { WellLabeledStatement StatementList? }

UnlabeledStatementFirstList:
    UnlabeledStatement
    UnlabeledStatementFirstList Statement

Statement:
    UnlabeledStatement
    LabeledStatement

UnlabeledStatement:
    Block
    VariableStatement
    EmptyStatement
    ExpressionStatement
    ContinueStatement
    ReturnStatement
    LabelUsingStatement
    DebuggerStatement

LabelUsingStatement:
    IfStatement
    IterationStatement
    BreakStatement
    WithStatement
    SwitchStatement
    ThrowStatement
    TryStatement

LabeledStatement:
    Identifier : Statement

WellLabeledStatement:
    Identifier : LabelUsingStatement
    Identifier : WellLabeledStatement

(I'm using the American spelling of "labeled" and "unlabeled". Can't help myself!)

Notice the right recursion in WellLabeledStatement's rule.

The idea is to allow

    javascript:42

and other such "not-well-labeled statements" for backward compatibility, but only at top level in SourceElement context. Not after a { that starts a Block.

After a { that starts a Block, you can have a label only if it is followed by a statement that could possibly use that label (labels may nest in such a WellLabeledStatement).

Any expression after a label that follows a { therefore must be the value part of a PropertyNameAndValueList in an ObjectLiteral.

This is a mostly-compatible change. Again props to crock for suggesting restrictions to label usage as a spark that kindled this fire.

If I have this right, then we could add a new production:

PrimaryExpression:
    Block

to allow blocks as expressions. We'd still need the [lookahead ∉ {{, function}] restriction in ExpressionStatement.

Making blocks be expressions allows us to treat them as zero-parameter block-lambdas: ({statements}) instead of the ugly ({|| statements}). The semantics would be the same as with a block-lambda: evaluation of the Block is deferred until it is called, typeof says "function", reformed completion value is implicit return value, etc. See:

http://wiki.ecmascript.org/doku.php?id=strawman:block_lambda_revival

(I haven't unified the above with the block lambda revival grammar yet; one step at a time.)

Grammar nerds, please validate!

/be
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110628/95cb81f9/attachment.html>


More information about the es-discuss mailing list