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