2024-02 の TC39 meeting
You are warmly invited to join us in San Diego for the @sandiegojs x @TC39 Community Event in celebration of the 100th meeting 🎉 We shall have talks, activities, hot appetisers, drinks, and lots of JavaScript 👍
It begins at 5pm on Thursday 8th Feb at the ServiceNow office.
https://gyazo.com/44920109617c4a3d9edd1af7408d4113
まとめ
決まったこと
Web compatibility issues / Needs Consensus PRs
process document のテーブルが更新された。
Allow locale based ignorePunctuation default for Collator tc39/ecma402#833 | Frank Yung-Fong Tang "th" ロケールのように、CLDR にデフォルトで句読点を無視するように規定されているものがある。これに対応するべく Intl.Collator の初期化時に [[ignorePunctuation]] 内部スロットを追加する Normative Change。
承認された。
ApplyUnicodeExtensionToTag and ResolveLocale set the result record's internal slots to non-canonical values tc39/ecma402#846 | Frank Yung-Fong Tang Allow Annex B scripts to start with --> (#3244) | Nicolò Ribaudo Annex B で既に行末後に HTMLCloseComment --> が記述できる。これに加えて Web Reality を反映させるためスクリプト先頭で --> を許容するようにする Normative Change。
モダンブラウザでは以下のようなテストケースで実行できるらしい。
code: js
eval("--> foo\nconsole.log(123)");
code: js
--> foo
console.log(123);
承認された。
現状グローバルスコープで変数の再宣言を起こさないために以下の制約に違反すると SyntaxError を投げるようになっている。
1. var や function で宣言された変数と同名の変数を let や const で再宣言する
2. globalThis の non-configurable なプロパティ名と同名の変数を let や const で再定義する
3. [[VarNames]] に登録された名前と同名の変数を let や const で再定義する
このうち 3 は eval("var x;") で変数被りを防ぐためのものだが、ユースケースがない割に実装コストが高いため、仕様から取り除く Normative Change。
Stage 4 (ES2024)
Stage 4 になった 🎉
Stage 3
今までは Set の要素数を取得する仕様が明確になってなかったため、delete で歯抜けになったら要素数に齟齬が生じうる仕様になっていた。その曖昧性をなくす変更が入った。
複雑になった仕様のリファクタリングをしている。
Temporal update & proposed normative changes (slides) | Philip Chimento 4つの Normative Change があった。
既に存在している Uint8Array に対して書き込む際に Uint8Array.fromBase64Into(base64str, array, options) となっていたのが Uint8Array#setFromBase64(base64str, options) に変更になった。Hex も同様。
Stage 3 になった。
Stage 2.7
Web API で ShadowRealms にいれるものが大まかに決まったっぽい。
https://gyazo.com/e5dc9cdd6f4e4509569c2c51c312c88e
安全性への懸念が理由だが postMessage が入らなかったのが意外だった。Stage 2.7 になった。
Stage 2
RegExp.escape hex escape discussion + for stage 2.7 | Jordan Harband Hex escape を入れることになった。
前回 throw 文と throw 式の優先度の違いなどの理由からブロックされていた。
code: js
throw 1 + 2; // throws 3
(0, throw 1 + 2); // throws 1
これを解決するために throw 式を使う場合は基本的に括弧で括らないといけないという話になった。
code: js
(throw a, b); // evaluates 'a', throws 'b'
さてこれを成し遂げるための文法として
1. throw を Expression にいれる
2. throw を ParenthesizedExpression にいれる
ことが考えられるが、どうするか議論された。
どちらのオプションも微妙ということになったので、他の方法を模索することになった。
Promise#then と似ているが、非 Promise がわたってきた場合にマイクロタスクを作らない Promise.try の提案。
Stage 2 になった。
Stage 1
Iterator を直列に結合する提案。どういう API にするが議論されていたが、Iterator.from と Iterator#flat が入ることになりそう。
flat に対するユースケースと、パフォーマンスについての懸念が出て Stage 2 にならなかった。
Iterator を並列に結合する提案。前回 Iterator.zip とするという話になっていたが、どうやら Iterator.zipTo{Arrays, Objects} になっている。
シンタックスが変わった。
code: js
const Point({ x, y }) = point;
Math.sumExact にリネームされ、引数が Iterable になった。
Stage 2 にはならなかった。
WasmGC の Shared Memory と Shared Structs が手を組んだ感じ。
Unicode CLDR で MessageFormat 2 がフィーチャーフリーズした。ところで MessageFormat のパーサーをどのタイミングでいれるべきか議論された。
1. MF2 が Unicode CLDR で仕様化され、十分な安定性が保証されたとき
2. もう安定しているものとして入れてしまう
そもそも MessageFormat 2 自体がまだ使われていないので、仕様にパーサーを入れるのは一旦待とうという話になった。
Iterator で一意の値のみを取り出す提案。
code: js
Iterator.from("Mississippi").distinct(); // "M", "i", "s", "p"
Stage 1 になった。メソッド名はまだ未定っぽい。
Iterator をチャンク化する提案。
Stage 1 になった。
SharedArrayBuffer のロックを取るときに現状 Atomics.wait を使う必要があるが、非常に短い時間で開放される場合はスピニングするとカーネルを経由しないため高速化出来る。
code: js
// Fast path
let spins = 0;
do {
if (TryLock()) {
// Lock acquired.
return;
}
SpinForALittleBit();
spins++;
} while (spins < kSpinCount);
// Slow path
PutThreadToSleepUntilLockReleased();
このスピニングを達成するために新たに Atomics.microwait(iterationNumber) を追加する提案。
Stage 1 になった。
Stage 0 の段階では Web Workers のために import module を追加する話になっていたが、import source として既にある Stage 3 Module Source Phase Imports と一緒になったようだ。
code: js
import source myModule from "./my-module.js";
// { type: 'module' } can be inferred since myModule is a module object
const worker = new Worker(myModule);
Stage 1 になった。
テンプレートリテラルを使う場合でも \` や ${ が入る文字列の場合エスケープが必要になってしまう。
code: js
let query = `
select *
from \users\
where \name\ = ?
`;
これは String.raw で解決できないため、新たな文字列リテラルを追加する提案。
code: js
// syntax TBD, just use @sken130 's strawperson draft as demo
let query = @
select *
from users
where name = ?
;
Stage 1 になった。
破棄する変数に予約語の void を使う提案。
例えば Stage 3 Explicit Resource Management に対しては
code: js
{
using void = new UniqueLock(mutex);
}
オブジェクトシンタックスの分割代入に対しては
code: js
const { z: void, ...obj } = { x: 1, y: 2, z: 3 };
obj; // { x: 1, y: 2 }
となる。また配列シンタックスのの分割代入だと消費する Iterator が明確になるメリットがある。
code: js
const a, void = iter; // author intends to consume two elements const a, void, void = iter; // author intends to consume three elements 引数にも便利。
code: js
// project an array values into an array of indices
const indices = array.map((void, i) => i);
Stage 1 になった。
関数宣言とオブジェクトリテラルのメソッドに Decorators を追加する提案。
code: js
// logging/tracing
@logged
function doWork() { ... }
// utility wrappers
const onpress = @debounce(250) (e) => console.log("button pressed: ", e.pressed);
// metadata
@ReturnType(() => Number)
function add(x, y) { return x + y; }
// React Functional Components
@withStyles({
root: { border: '1px solid black' },
})
@React.forwardRef
function Button(props, forwardedRef) {
...
}
Stage 1 になった。
Decorated Function Declarations and Hoisting (slides) | Ron Buckton 関数宣言の Decorators には hoisting の問題がある。今のところ5つのオプションが考えられるが、チャンピオン的には Decorated Functions は hoisting しないことを支持している。
https://gyazo.com/733fa7ed9e5e9ed79019f57f2c940440
その他
status of the IEEE Software paper about TC39 (slides) | Mikhail Barash Language Design In The Open: How ECMAScript (JavaScript) is Standardized として IEEE Software paper に論文を書くとのこと。
Ecma Recognition Awards | Chris de Almeida, Samina Husain
TG5 charter and chair(s) appointment (slides) | Mikhail Barash ECMAScript がどのように標準化されているのかを研究、普及する TG5 が出来た。
Can we reach consensus on what is Consensus? (slides) | Michael Saboff 総括