Because the LabelledStatement changes in http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax restrict labels to prefix only LabelUsingStatements. I was addressing the backward incompatibility here: ES1-5 allow useless labels. You seemed to think that incompatibility was important enough to require new label syntax, but I argued that it is (a) not important; (b) caught by early error during migration.

Ok, so you want to restrict label use. But syntax alone cannot
guarantee that a given label prefix is ever actually used, it can
only rule out alternatives that cannot possibly use the label. And introducing such syntactic restrictions on label use means that one can no longer insert labels without thinking about
whether they can be used because inserting unused labels
might require rewriting the code. In any case, the result is that both parser writers and developers have to think about the restrictions that make labeled Statements different from Statements.
I still have a few blind spots where things that I thought
about for this class of language are not actually permitted by the Javascript grammar, so perhaps LabelUsingStatement won't introduce enough additional complexity to worry about. But, generally speaking, I'd prefer to remove
complexity from the grammar, rather than add it.

It isn't that I like labels, but if labels are permitted, I prefer them not introducing additional complexity that I have to think about. So my comments were based on not having
the LabelledStatement changes, addressing the ambiguity
in another way.

Without changes, any grammar that has ObjectLiteral and
Block as alternatives is ambiguous:

   ObjectLiteral | Block    // ambiguous

Assuming we want to resolve ambiguities by preferring
ObjectLiteral, we could write

   ObjectLiteral | (Block butnot ObjectLiteral)

where the right branch is the implicit grammar for what you are aiming to spec explicitly, by removing the ambiguous cases from Block, specifically from LabelledStatement, to
give us some form of RestrictedBlock that doesn't conflict
with ObjectLiteral. So we can combine both in arrow bodies

   ObjectLiteral | RestrictedBlock

(PEG-style grammars could make that even more implicit,
via ordered choice: anything that is a valid ObjectLiteral can no longer reach the second alternative)

The problem I have with that is that I need to think far
ahead to figure out whether I'm writing an ObjectLiteral
or a RestrictedBlock and that I need to be aware of whether the Statement I'm writing follows a label or not.

So I'm looking for a way to introduce a committed choice
based on limited lookahead instead. It seems that the
IdentifierName (PropertyName) vs Identifier (label) case
is the one that can lead to long lookaheads, so breaking
that seems a step forward. Hence the new-style labels.

It is not necessary to remove old-style labels right away,
because old code that uses them only uses old language
constructs (which never mix ObjectLiteral and Block). For
code that opts into Harmony, a deprecation warning for
old-style label seems appropriate, but we don't need to
force code rewrites of old code.

For any new language constructs that do mix ObjectLiteral and Block, such as arrow syntax, we can arrange that '{ Identifier : .. }' always defaults to ObjectLiteral, no matter what comes next. In these positions, old-style labels are useless, but new language constructs are only used in new code, so we can ask developers to use new label syntax if they want a Block starting with a label in such positions.

In grammar terms, the arbitrary lookahead alternative

   ObjectLiteral | (Block butnot ObjectLiteral)

turns into something like

   ObjectLiteral | (Block butnot ('{' (Identifier|StringLiteral) ':' .*)

If this works out, parsers and programmers can commit to one of the alternatives after a limited lookahead, no matter what comes next. Committed choice also means
no backtracking, so '{ empty: ; }' would be an invalid
ObjectLiteral, not a valid Block, if used as an arrow body
(while '{ :empty: ; }' would be an empty block). So there are pros and cons - the means of disambiguation are easier to understand, but not as expressive.

Now I don't see any solution in adding new label syntax. Having to parse the old one leaves us with the ambiguity. What am I missing?

Old labels in old code don't use new features, like arrow
syntax, so the ambiguity does not surface. Old labels in new code using arrow syntax will be overlapped by object property names, so the ambiguity is resolved. New labels in new code using arrow syntax allow to override the
default ambiguity resolution.

but add labels starting with, say ':' (just to pick a prefix).
We really don't want two label syntaxes, ..

Right. The old syntax could be deprecated (when opting in
for ES/next) - it also doesn't allow label parameters or
label variables.

Do you mean prohibited or deprecated? Usually deprecation means a warning, obsolescence or prohibition means removal.

Deprecation, with removal not before ES/next/next.

Of course, changing label syntax might give the impression that labels are an encouraged feature, which isn't quite right.

Yes, the strawman proposes to break such code. So requiring {; or similar would be a simpler change and non-breaking in the sense that one can rescue such code so it works in Harmony as it used to, by adding one character. Good idea!

Thanks.

Claus

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to