Motivation

Syntax matters, keystrokes count. Both readability and writability can be impaired by too much punctuation and unnecessary bracketing. Some languages even prefer indentation-based block structure to bracing, and their fans report read and write (including keystroke and RSI avoidance) wins.

JS has a number of statement forms with mandatory parentheses around the head. Can we relax syntax without introducing ambiguity or bad human read/write factors? This proposal makes an attempt, first described here and prototyped in Narcissus via the –paren-free option.

A specific motivation for this proposal is the irredeemable for-in loop, whose semantics have been underspecified forever, with ongoing divergence among implementations, and where array comprehensions and generator expressions do not want parenthesized for-in heads, yet where users do want better semantics for all for-in variants.

History

JS derives from Java from C++ from C (via early C and B), from BCPL. BCPL had paren-free if, etc., heads disambiguated via do reserved words to separate an expression consequent, avoiding ambiguity.

JS style guides often favor mandatory bracing of if consequents and other sub-statement bodies, which also suffice to avoid ambiguity about where the condition or head expression ends and the dependent sub-statement starts.

Proposal

Consider ES5 12.5, “The if Statement”, modified as follows:

IfStatement :
    if Expression SubStatement else SubStatement
    if Expression SubStatement
    if ( Expression ) OtherStatement else Statement
    if ( Expression ) OtherStatement

Where SubStatement is

SubStatement :
    Block
    KeywordStatement

and KeywordStatement is

KeywordStatement :
    IfStatement
    IterationStatement
    ContinueStatement
    BreakStatement
    ReturnStatement
    SwitchStatement
    ThrowStatement
    TryStatement
    DebuggerStatement

This leaves

OtherStatement :
    EmptyStatement
    ExpressionStatement
    VariableStatement
    LabelledStatement

and

Statement :
    Block
    KeywordStatement
    OtherStatement

The same pattern applied to IfStatement above applies to IterationStatement, SwitchStatement, and catch clauses in TryStatement – except catch blocks must still be braced (as with try and finally since their introduction in ES3), so no OtherStatement catch body production.

TODO: expand these all into a complete sub-grammar.

We allow single sub-statements starting with unconditionally reserved keywords to be unbraced after a paren-free head, since the keyword acts as BCPL’s DO separator to disambiguate head from body expression.

Notice how this relaxation from requiring braces around the body allows if-else-if chains (idiomatic since K&R C and unproblematic as far as dangling-else goes) without a special case:

  if x < y {
  } else if x < z {
  } else if x < w {
  } else {
  }

instead of the perfidious rightward drift of:

  if x < y {
  } else {
    if x < z {
    } else {
      if x < w {
      } else {
      }
    }
  }

This keyword-or-brace refinement also matches some popular style guides that recommend braced bodies except where the body is a short keyword-prefixed statement starting with break, continue, throw, or return.

Note that the paren-free if-else production requires the else clause to be a SubStatement. You cannot write if x > y { alert(”win”); } else alert(”lose”).

For backward compatibility, we support parenthesized heads with any sub-statement. To preserve the LR(1) grammar this requires factoring out OtherStatement.

Thus, this proposal is intended to make no backward-incompatible syntactic or semantic changes to ES5. “Paren-free” is now purely a relaxation of syntax rules.

Brendan Eich 2011/06/05 21:06

 
strawman/paren_free.txt · Last modified: 2011/06/05 21:07 by brendan
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki