Unresolved 3.1 issue: statements and substatements
I agree with reverting the breaking change to non-strict mode. In
general I think it is unacceptable to make any incompatible changes to
standard mode without careful review of implementations and some study
of existing Web content to ensure they are safe.
I'm not sure what the benefit is of making the change in strict mode
only. It would be nice if ECMAScript were a block-scoped language, but
it isn't, and I am not sure disallowing var as an if or switch clause
is particularly helpful, especially when it is still allowed inside a
block serving in such a clause.
I also agree that labels should be left alone. They are not a very
commonly used feature and not especially a programming hazard, so they
do not seem worth a special strict mode rule.
I agree with reverting the breaking change to non-strict mode. In general I think it is unacceptable to make any incompatible changes to standard mode without careful review of implementations and some study of existing Web content to ensure they are safe. I'm not sure what the benefit is of making the change in strict mode only. It would be nice if ECMAScript were a block-scoped language, but it isn't, and I am not sure disallowing var as an if or switch clause is particularly helpful, especially when it is still allowed inside a block serving in such a clause. I also agree that labels should be left alone. They are not a very commonly used feature and not especially a programming hazard, so they do not seem worth a special strict mode rule. - Maciej On Nov 9, 2008, at 2:08 PM, 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. > > _______________________________________________ > Es-discuss mailing list > Es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20081109/d20404ac/attachment-0001.html>
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
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
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.