Suggestion: Getting a handle on ASI usage

Claus Reinke claus.reinke at talk21.com
Wed May 11 09:06:34 PDT 2011


Background assumptions: 

    Fixing ASI, as desirable as that may be, is not going to
    happen soon. Neither is the transition going to be quick 
    if/when a better alternative emerges, as existing ASI usage
    patterns need to be supported. 

    However, these usage patterns are currently not clearly 
    identified - there seem to be multiple schools of ASI usage, 
    with different needs and intentions, and implementations 
    cannot guess intentions.

Idea:

    Start by giving javascript programmers the ability to declare
    their intentions wrt ASI usage. That way, future attempts at
    ASI improvements will have a better handle on what they
    need to preserve, and what they can change. 

    Even without ASI changes, such declarations will allow 
    implementations to give better warnings (no need to guess 
    user intentions), helping to avoid current ASI pitfalls.

Suggestion (outline; syntax and details up for discussion):

    Introduce a language pragma for ASI, accompanied by
    warning pragmas (a "language pragma" indicates use of a
    language feature, as a modular alternative to language
    versions; a "warning pragma" indicates use of an
    implementation option). 

    Lacking a javascript standard for pragmas, this suggestion 
    follows the "use strict" example (string expression statements 
    with function or script scope):

    Language pragma:

        "ASI:on"; // to indicate maximal use of ASI

        "ASI:off"; // to indicate minimal use of ASI

    Warning pragmas:

        "ASI:warn-insert:[on/off]"; 
            // warn about unexpected semicolon insertion

        "ASI:warn-no-insert:[on/off]";
            // warn about missing semicolons

        (examples of "unexpected"/"missing" are given below)
        
    Implied warnings:

        The default for ASI warnings is "off" (no warnings).
        Use of "ASI:on" shall imply "ASI:warn-no-insert:on".
        Use of "ASI:off" shall imply "ASI:warn-insert:on".
        Implied warnings can be reset by explicit warning
        pragmas.

    Phase 1: (the current suggestion; as soon as possible)

        Implementations supporting ASI pragmas must run code 
        *with or without* ASI pragmas as before, but must provide
        checks and warnings (on a side channel, such as an error 
        console) for code *with* ASI pragmas.

    Phase 2: (depending on implementer/programmer buy-in
                     to phase 1; probably not anytime soon)

        Implementations supporting ASI pragmas must run code 
        *without* ASI pragmas as before, but could treat ASI 
        warnings for code *with* ASI pragmas as errors. 

        One could also start to issue deprecation warnings for 
        code without ASI pragmas, encouraging transition to
        ASI usage pattern documentation, and one could evaluate 
        ASI usage patterns, as declared by use of ASI pragmas in 
        real-world code. 

        Warning-free code with ASI pragmas should both offer 
        good test-cases for any ASI modifications and document
        programmer intentions for any transition support tools.

Observations and clarifications:

As far as I can tell from the previous ASI thread, there are several 
groups with opinions about ASI, including (but not limited to):

A those who avoid semicolons, relying on ASI to fill them in
B those who avoid ASI, writing out all semicolons explicitly
C those who expect newlines to imply semicolons, with mixed
    results, because that isn't the way ASI works

These groups have different problems with ASI, even assuming
that both A and B know and understand how ASI works:

A have to insert semicolons where ASI does not kick in
B have to be wary of ASI inserting unwanted semicolons
C tend to find ASI confusing

As long as we don't have a better solution, it seems that warning
about the unexpected/unwanted might improve understanding
and user experience of ASI as it stands. This should also prepare
the ground for any ASI improvements/replacements.

Currently, implementations cannot issue warnings - they are
handling ASI as specified and they cannot guess whether or not
that matches programmer intentions; however, once programmers 
declare their ASI usage pattern (maximal/minimal), there are two 
well-known trouble spots that can trigger warnings. 

Both of these trouble spots are related to newlines (either the 
programmer expects a newline to insert a semicolon, but ASI
does not apply, or the programmer expects no inserted 
semicolons, but ASI is triggered by a newline):

(a) warn if two consecutive statement lines of equal indentation 
        are not separated by explicit or inserted semicolon
(b) warn if restricted production or error correction insert 
        semicolon at a newline that is followed by extra indent

For warnings to be useful, it must be possible for coders to
avoid them on a case-by-case basis, without disabling the
warning entirely - this is here supported based on the idea 
of indentation (*only* used for controlling these warnings):

a can be silenced by having the next line indented further,
    to indicate continuation of statement on previous line
b can be silenced by having the next line indented equally,
    to indicate start of new statement

The choice of indentation for warning control is intentional,
as it will offer feedback on whether a significant whitespace
approach to semicolon insertion would work for Javascript
developers, without going all the way towards introducing 
such a change (although ASI already is whitespace-dependent, 
via newlines).

Warning (a) should be included in "ASI:warn-no-insert", 
warning (b) should be included in "ASI:warn-insert". It might
be possible to include warnings for other pitfalls, if they can 
be identified and silenced unambiguously.

The warnings should be opt-in (by pragma), and on a side 
channel (like HTML/CSS parser errors), visible to developers 
and interested users, but not to viewers only interested in 
content. Group A will want to use "ASI:on", and get some 
help with missing semicolons, group B will want to use 
"ASI:off", and get some help with unwanted semicolons, 
group C might be helped by using both warnings.

Does this sound useful to all parties?
Claus

// examples

function restricted_production() {
  "ASI:off";
  return  //;
        "hi"; // warn here, provided this line is indented
}

function newline_no_asi() {
  "ASI:on";
  var x = ["hi"] //;
  [1];  // warn here, unless this line is indented
  return x;
}

function newline_error_asi() {
  "ASI:warn-insert";
  var a = "hi"+
          "ho";
  var b = "hi"  //;
          "ho"; // warn here, provided this line is indented
  return a==="hiho" && b==="hi";
}

log( restricted_production() || 
     "newline in restricted production inserts semicolon" );
log( newline_no_asi()        || 
     "newline alone does not insert semicolon" );
log( newline_error_asi()     && 
     "newline followed by error inserts semicolon" )

/*
 * suggestions:
 * - warn if inserted semicolon is followed by indented line
 * - warn if non-indented line is not preceded by implicit or explicit 
semicolon
 */
  


More information about the es-discuss mailing list