Unresolved 3.1 issue: statements and substatements

Waldemar Horwat waldemar at google.com
Mon Nov 10 17:44:21 PST 2008


As you noted, we can't break existing usages of var:

if (foo)
  var x = 3;

As such, var statements should be considered to be substatements and allowed anywhere.  The declaration scope syntax rules would only apply to const and function declarations (and, in the future, let).

I don't see any benefit of getting strict mode involved with this -- the syntax ought to be the same with or without strict mode.  var's are already hoisted, so the question of which block they're in is moot.

    Waldemar


Allen Wirfs-Brock wrote:
> The ES3 specification has a single grammar production /Statement/ that 
> specifies what can occur in nested statement contexts such as if 
> statement then and else clauses.  This allows for some strange looking 
> but valid code such as:
> 
>  
> 
> If (foo)
> 
>    var bar = “baz”;
> 
> else
> 
>    var bar = “bam”;
> 
>  
> 
> for (var i=0;  i<10) var i=i++;
> 
>  
> 
> switch (i) {
> 
>    case 0 : var s = “one”; break;
> 
>    case 1:  var s = “two”; break;
> 
>   default: var s = “other”;
> 
>  }
> 
>  
> 
> ES3.1 drafts have split /statement/ into separate /Statement/ and 
> /SubStatement/ productions.  /SubStatement/ excludes /VariableStatment/ 
> (and for a while,  when we had them, function and const statements) and 
> is used in most nested contexts such as the above. In the revised 
> grammar, nested /Statement/ productions only occur as the body of blocks 
> and as function bodies.  The motivation for this split was twofold.  The 
> primary reason was in support of blocks introducing nested lexical 
> declaration environments. There was discussion regarding whether or not 
> such nested declarations without explicit block braces should be 
> considered to be in an implicit lexical block.  In particular, some of 
> us didn’t want to further propagate to const and let the var-like 
> possibility of multiple declarations within a lexical block of the same 
> entity. For example, the thinking was that:
> 
>  
> 
> If (foo)
> 
>    const bar = “baz”;
> 
> else
> 
>    const bar = “bam
> 
>  
> 
> should either be illegal or  useless (each const would be in a separate 
> implicit lexical block and would disappear immediately at completion of 
> the block).  The “illegal” possibility was preferred and /SubStatement/ 
> was created as a way to specify that.
> 
>  
> 
> The second motivation of the split was a hygienic objection to the 
> occurrence of var  (or any new declarations) in such positions. The 
> belief was that most users who might code such things probably don’t 
> understand the actual semantics  involved and may or may not get the 
> result they expected. If this is the case, it is probably better to 
> forbid it.
> 
>  
> 
> The exclusion of var from SubStatement is a breaking change to ES3.  
> Some potentially existing valid ES3 programs that used var in these 
> sorts of nested scenarios would not be valid ES3.1 programs. However, at 
> the time, the combination of the two motivations seemed to carry enough 
> weight to justify the change.
> 
>  
> 
> However, we have not included lexical blocks or any new lexical 
> declarations in 3.1 and while we will eventually have them it seems 
> unlikely that var will ever have block local scope. So the first 
> argument doesn’t really apply in the context of 3.1. The hygiene based 
> argument is of the sort that we have generally only applied to strict 
> mode restrictions. Strict mode is opt-in so minor breaking changes can 
> be tolerated in strict code.
> 
>  
> 
> Recommendation #1:  For non-strict mode code, ES3’s support of 
> /VariableStatement/ in nested contexts remains in place. The above code 
> examples remain valid non-strict ES3.1 code. However, ES3.1 strict mode 
> will disallow such usage of /VariableStatement/. Whether this is 
> accomplished via some variant of the current draft’s 
> /Statement///SubStatement/ grammar or via prose restrictions for strict 
> mode is a specification detail that can be resolved after we make this 
> decision.
> 
>  
> 
> Assuming we follow that recommendation (or if we don’t and continue to 
> apply the restriction to all code) there is still another open question 
> about the strict mode semantics.  It is, can a /VariableStatement/ occur 
> as the /Statement/ of a /LabelledStatement/.  For example, the following 
> is currently allowed in ES3:
> 
>  
> 
> IntegerVariables:
> 
>    var i,j,k,l,m,n;
> 
> StringVariables:
> 
>     var A$,B$, C$;
> 
>  
> 
> Odd, but valid in ES3.  More generally, ES3 allows any statement to have 
> a label including all non-compound statements that can’t possibly 
> contain a break or continue.
> 
>  
> 
> Strict mode could restrict such usages and this is probably a good idea 
> if you believe that one of the purposes of strict mode is to enable 
> early flagging of code whose meaning is likely not to be what a 
> programmer intended.
> 
>  
> 
> My opinion (but not a recommendation) is that we should probably just 
> leave /LabelledStatment/ alone for ES3.1, even in strict mode. However, 
> we certainly could specify some strict mode restrictions for it  if 
> there is a consensus that they are desirable. So:
> 
>  
> 
> Feedback Request:  Should we restrict usage of LabelledStatment in 
> strict mode or leave it as specified in ES3.
> 
>  
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Es3.x-discuss mailing list
> Es3.x-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es3.x-discuss



More information about the Es-discuss mailing list