TC39 meeting, March 9-10 2021


This meeting marks the first of a series of shorter meetings, which will hopefully help us stay focused and more productive. TC39 has updated its process to have 8 meetings a year, instead of the usual 6, with 4 regular length meetings and 4 short two-day meetings. This being the first of that cycle. You may notice that these updates are a little shorter than usual.

On to the proposals: Temporal, the long awaited time/date library, has conditionally advanced to stage 3. This comes with a warning, however, this proposal must not ship unflagged until IETF standardizes timezone/calendar string serialization formats. (See #1459) This means that Implementers can start work on making the proposal, and the API is stable, but we are waiting on another standards body. If you would like to try it ahead of time, they have created a cookbook and polyfill for experimentation.

Error cause, a new proposal, also advanced to stage 3. Error cause will help developers be descriptive about the reason why a certain error occurred. You can use it in the following pattern:

throw new Error('Error message Text', { cause: anotherError });

This should help make debugging nested errors more efficient. In Firefox, we had a non-standard second argument that is no longer in use, but there are no issues around web compatibility, as our implementation took a number and this will be an object.

A new, exciting proposal is Module Fragments presented by Daniel Ehrenberg. Module Fragments would allow bundlers to target a browser format that may in the future make bundling and working with modules on the web easier and more efficient. This proposal adds syntax which will allow the definition of multiple modules in one file.

Needs minor change:

None.

Keep an eye on…

  • Collection normalization.
  • Unicode Set notation.
  • module Fragments

Normative Spec Changes

Make B.1.{1,2} (octal literals & escapes) normative for sloppy code

  • Notes
  • PR
  • Summary: Part of an editorial project to move all of Annex B into the main body of the specification. There is some contention about this topic, in that Annex B is not a valid LR(n) grammar. However, the separation between Annex B and the rest of the spec has caused issues, for example when main body spec text is modified by Annex B, resulting in unexpected behavior for spec authors and others.
  • Impact on SM: None
  • Outcome: Consensus.

Backup incumbent tracking for FinalizationRegistry jobs

  • Notes
  • Slides
  • PR
  • Summary: In the browser, there are contexts in which a promise or finalization registry runs, but its settings object is unclear. Promises have solved this by restoring a specified settings object. The purpose of this change is to align FinalizationRegistry callbacks with Promise callbacks in allowing web browsers to perform additional steps to save and restore the correct incumbent settings object. This was one of the blockers in the HTML integration PR for WeakRefs and the FinalizationRegistry, proper handling of backup incumbent settings objects. This aligns with the Promise implementation, and Firefox has already implemented this. This was previously discussed a few meetings ago but fell off everyone’s radar.
  • Impact on SM: None
  • Outcome: Consensus.

Normative: specify creation order for capturing group properties

  • Notes
  • PR
  • Summary: The order in which the non-numeric properties are created (i.e. those from named capturing groups) is observable with Object.keys.
  • Impact on SM: None, spec aligns with engines now
  • Outcome: Consensus.

Proposals Seeking Advancement to Stage 4

None.

Proposals Seeking Advancement to Stage 3

Error Cause for Stage 3

  • Notes
  • Slides
  • Proposal Link
  • Summary: Catching an error and re-throwing it with contextual information is a common approach to error handling. To make this easier, this proposal adds a second argument to Error which provides the cause.
  • Impact on SM: SpiderMonkey implements multiple arguments for Errors, but they do not appear to be used. Additionally the options bag makes this not a compat risk.
  • Outcome: Advanced to Stage 3.

Temporal for Stage 3

  • Notes
  • Slides
  • Proposal Link
  • Summary: Introduces a new date/time library. If you would like to try it ahead of time, they have created a cookbook and polyfill for experimentation.
  • Impact on SM: Needs Implementation, must not ship unflagged until IETF standardizes timezone/calendar string serialization formats.
  • Outcome: Conditionally Advanced to Stage 3.

Collection Normalization for Stage 3

  • Notes
  • Proposal Link
  • Summary: Various data structures are expected to have consistent constraints and or normalization applied to their keys and/or values when being used after creation. For example, a map may contain a collection of urls, which need to have their values initialized into some sort of data structure. The current workflow is to manually ensure that at all locations which insert data into the structure properly normalize the data. This leads to various issues such as potentially fragile boilerplate problems including: normalization not applied to all insertion locations or normalization not applied in consistent manners across insertion locations. This proposal does add a new capability of guarantees around the stored values in these data structures. Currently calling various methods on built-ins can avoid any mechanism to intercept and normalize data as it is inserted by calling methods on a structure like Map.prototype.set.call(mapOfStringsToStrings, number) which prevents guarantees about a Map having a consistent set of guarantees about the data it contains.
  • Impact on SM: None yet.
  • Outcome: Did not advance due to disagreements about how a Set should be normalized, and how generic programming should be supported. The current suggestion to address this is Map would take value or key or both or neither, and Set would take key or value or neither, but would throw if you gave it both, and that would then satisfy all of the key mental models and use cases and the only thing it would throw on for Sets is the nonsense combination of the key and the value coercer.

Resizable ArrayBuffer for Stage 3

  • Notes
  • Slides
  • Proposal Link
  • Summary: Introduces two new ArrayBuffers, one resizable, the other only growable (and shared). The update to resizable ArrayBuffers introduces implementation defined rounding.
  • Impact on SM: Would require potentially significant changes.
  • Outcome: Did not advance. There were two objections, one was ours – we requested that rather than implementation defined rounding, we set a recommendation similar to WASMs. The other was that work was done in the WASM specification to ensure we are aligned.

Stage 3 Updates

Intl.Segmenter

  • Notes
  • Proposal Link
  • Spec
  • Slides
  • Summary: Intl.Segmenter will allow programmers to do sentence segmentation according to locale. The champion changed course and turned this into an update for stage 3 rather than a request for stage 4, in order to give time for the ICU4x work to complete.
  • Impact on SM: Implementation paused, awaiting ICU4X work,

Class static Initialization Blocks Stage 3

  • Notes
  • Proposal Link
  • Slides
  • Summary: An update to the stage 3 advancement from last meeting. Class Static Initialization allows creating a block in which class fields can be initialized. It takes the following form:
    export class C {
      #x
      constructor(x) {
        this.#x = { data: x };
      }
    
      static {
        // getX has privileged access to #x
        getX = (obj) => obj.#x;
      }
    }
    

    The update for this meeting focused on a couple of outlying issues, Issues #26 and #25, which are now resolved.

  • Impact on SM: Requires implementation,

Top-level await update towards stage 4, DFS ordering invariant normative change and bug fixes

  • Notes
  • Proposal Link
  • Slides
  • Summary: A bug was found during implementation and fuzzing, the cycle root was incorrectly identified resulting in incorrect behavior. The other issue, DFS ordering, is related to the developer’s expectation when executing a graph that is entirely sync, with a shared leaf node. Changing that leaf node would result in reordering the graph, as we were not tracking the post order of the modules. This is bit unintuitive. This was not a bug, but an oversight. The committee moved to change this behavior to something more intuitive.
  • Impact on SM: Implementation complete, no change
  • Outcome: Consensus on both counts.

Proposals Seeking Advancement to Stage 2

Array find from last

  • Notes
  • Proposal Link
  • Slides
  • Summary: Proposal for .findLast() and .findLastIndex() methods on array.
  • Outcome: Advanced to stage 2

Stage 2 Updates

None

Proposals Seeking Advancement to Stage 1

JavaScript module fragments for Stage 1

  • Notes
  • Proposal Link
  • Slides
  • Summary: Introduces syntax which will allow multiple modules to be defined in a single file, without access to any enclosing scope state. This will potentially unlock really useful applications for bundlers.
  • Outcome: Advanced to stage 1

Stage 1 Updates

do and async do expressions

  • Notes
  • Proposal Link
  • Slides
  • Spec
  • Summary: Write in an expression-oriented style, scoping variables as locally as possible:
    let x = do {
    let tmp = f();
    tmp * tmp + 1
    };
    
  • Impact on SM: None.
  • Outcome: A user research study will be run to determine if there is an issue with continue, break, and return.

Adopting Unicode behavior for set notation in regular expressions

  • Notes
  • Proposal Link
  • Slides
  • Summary: Add syntax & semantics for the following set operations: difference/subtraction (in A but not in B), intersection (in both A and B), nested character classes (needed to enable the above)
  • Outcome: Update regarding the decisions made in the incubator call.

Other Updates

  • The records and tuples champions brought for discussion array-by-copy methods as a potential direction to have a clear overlap between mutable and immutable methods. This will be split into its own proposal.
  • The pipeline operator is seeking a new Champion, and has likely found a few.
  • Promise.race was introduced to be renamed as Promise.allSettled. This didn’t reach consensus yet.