Description
In the June 2019 TC39 meeting, @erights raised the topic of Annex B reform. We reached consensus on two high-level points, but there remain many details to work out, which I'd like to elaborate on in this thread:
- Many Annex B things could be made normative
- The remaining Annex B items would be placed inline, with markup indicating that they are normative optional
In some more detail:
Making some Annex B things normative
The lens proposed by @erights was that we make normative everything which is "perfectly safe from a non-locality, causality perspective".
Of particular concern are grammar issues, where having multiple divergent grammars (both for HTML comments and RegExp grammars) leads to security and implementer confusion issues. Mark also proposed that other parts of the specification which are simply ugly, but not harmful from an SES/ocap perspective, be considered normative.
We didn't discuss what this means in detail, in particular, which things will go into the main spec. Based on the notes and my reading of the specification, I'd say that includes
- All grammar features, in particular, because divergence in grammars presents a security risk, in a notion of security that @erights and I agree on--if you're not scared, read The Tangled Web for some frightening anecdotes about security issues from divergences in grammars in Web protocols (which span client, server and IoT these days).
- B.1.1 Sloppy-mode legacy octal literals in numbers and B.1.2 strings (note, these would stay sloppy mode only)
- B.1.3 HTML-like comments (Note, these would stay prohibited in modules)
- B.1.4 RegExp grammar extensions (Note, this would continue to be non-Unicode-only)
- In my opinion, it would be fine to include a note that we are somehow sad about these parts of the grammar, if someone has an idea about the wording for such a note (e.g., "this form is deprecated, but implementations must support it"). But leaving them not just sad (in addition to being present only in older modes) but also optional has real cost.
- Most of B.2 Additional Built-in Properties (omitting B.2.5, RegExp.prototype.compile, see below)
- B.2.1 escape/unescape
- B.2.2 The
__proto__
accessor and pre-ES5 accessor API - B.2.3 substr and HTML generation functions
- B.2.4 Strange Date functionality
- Offline, @ljharb commented to me that things like
substr
are especially unfortunate, as we may want to discourage use of some of these. If we want to mark it specially, I'd suggest inline "normative deprecated" marking, rather than making it optional.
- B.3 Additional language constructs (omitting B.3.7, see below)
- B.3.1 proto in object literals
- B.3.2 Labelled function declarations (still restricted to sloppy mode)
- B.3.3 Block-level function declarations web compatibility semantics (my sloppy-mode-only old nemesis!)
- B.3.4 Function declarations in if statements (my current status: blood starting to boil. But still, let's make this normative, and maintain its sloppy mode restriction)
- B.3.5 Variable statements in catch blocks
- B.3.6 Initializers in for-in statement heads
Is any of the above in error?
Making Annex B inline
The general strategy for inline Annex B would be to follow what we've done with Intl for legacy constructor semantics. These are also "normative optional", but listed interspersed with other specification text. The idea is that this phrasing makes the text more readable, while preserving its optionality outside of web browsers. This should help avoid situations where people have read part of the specification, not realizing that another part modified it, resulting in confusion and non-Annex-B-compatible implementations when the intention was to be web-compatible.
See an example in the WeakRefs proposal of adding some inline Annex B text (PR), and similar text in Intl (PR).
@bterlson raised concerns about the accessibility of the Intl specification's normative optional text. I'm not an expert in this area; if someone has an idea for better CSS, or HTML generated from ecmarkup, it'd be great to have your help.
Items which @erights's presentation proposed to leave as normative optional, which I'd suggest should be inline normative optional:
- B.2.5.1 RegExp.prototype.compile
- NB: @erights raised the concern that this could violate how frozen objects work, but I don't think that's the case currently, as ES6 changed things from own properties to accessors.
- B.3.7 The document.all special behavior, which explicitly only works on the Web.
Future proposals which could be inline normative optional, per @erights's suggestions:
- WeakRef.prototype.constructor
- Function.prototype.caller, Function.prototype.callee, Function.prototype.arguments
- Error.prototype.stack
- RegExp legacy properties
Next steps
- Discuss the above plan in this thread, so we can iterate on it as needed (discussion is not blocking drafting PRs, but blocks landing them)
- Make a label for PRs towards this effort
- Write a PR for each of the bullet points above (fine if you decide to group or split these out differently)
- Several people can collaborate here. Check off the checklist items above once it's done (I believe all delegates should be able to edit this comment).
- Iterate on the styling/HTML of the normative optional section (if needed)
- In my opinion, "deprecation" language is not necessary, but if we decide on that as part of making some of these "normative", then we'd add a checkbox for this too.
- Bring the package of PRs to a TC39 meeting, asking for consensus