2020-09 の TC39 meeting
まとめ
決まったこと
Web compatibility issues / Needs Consensus PRs
MakeTime 仕様ミスの修正。承認された。
Annex B で定義されている __proto__ をちゃんとした仕様として ECMA-262 に盛り込む提案。__proto__ シンタックスとしては入るが、アクセサとしては今まで通りオプショナルということになった。
ビルトイン函数の name と length プロパティの定義順を仕様に組み込む提案。承認された。
ArrayBuffer の仕様内で TypeError を投げる一部の箇所が Web Reality と合ってないため修正する提案。承認された。
WebAssembly では Unicode として valid である文字列を名前としてエクスポートすることが出来るが、ECMAScript としてはそうなっておらず乖離が起きてしまっているため修正する提案。承認された。
函数の length の値を Infinity にし、Function#bind を使うとその新しく作られた函数の length が実装によって変わっているらしい。
code: (js)
function f(){}
Object.defineProperty(f, 'length', { value: Infinity });
console.log(f.bind(0, 1, 2).length);
code: (text)
#### ch
0
#### jsc
0
#### sm
Infinity
#### v8
Infinity
#### xs
9007199254740989
とりあえず Infinity を返すこととなった。
MakeTime には IEEE 754-2019 の演算に準ずるということが記載されているが、MakeDate にはない。承認された。
GetOption (issue, PR) | Philip Chimento ECMA-402 に新たに内部函数として GetOption を定義し、オプションのオブジェクトを受け取る函数でそれをつかう提案。ToObject よりも厳密で、バグを生みにくい。承認された。
Stage 4 (ES2021)
ブラウザが持っている翻訳文字列を取得することが出来る Intl メソッドの提案。Stage 4 になった 🎉
Stage 3
V8 では実装されており、JavaScriptCore や SpiderMonkey で実装が進んでいることが共有された。
indexable なクラスに対して item メソッドを追加し、引数に負数を入れた場合に後ろから値が取れる提案。String#item が code unit のインデックスとして扱われるようになった。
Stage 3 になった。
JSON Modules のために ES Modules に属性を追加する提案だったのが、アサーションの提案に変わった。
code: (js)
import json from "./foo.json" assert { type: "json" };
import("./foo.json", { assert: { type: "json" } });
Stage 3 になった。
Stage 2
Iterator Helper の Stage 3 のレビューアーを探している話。
Temporal において Absolute が Instance にリネームされたり、Duration のアップデートがされたりしたことが共有された。
https://gyazo.com/6313eb662e3c1a30cad5e67206efb42b
JSON Modules update (slides) | Sven Sauleau, Daniel Ehrenberg, Myles Borins, Dan Clark, Shu-yu Guo JSON Modules をただのオブジェクトとしてミュータブルに扱うのか、それとも Record/Tuple としてイミュータブルに扱うのか議論された。
以前 Symbol as WeakMap keys の中で話題に上がった Box についての issue がたっている。
また Record/Tuple をオブジェクト、プリミティブのどちらで扱うべきかが議論されている。
そして SpiderMonkey で実装が始まったらしい。
インスタンスに特定のプライベートプロパティがあるかどうかを調べるために in 演算子を使う提案。
新たな Decorators の提案として
プレーンな函数を使う
Decorators は構文であったり、プロパティについて修飾する
インターフェースとしては
code: (ts)
type Decorator = (value: Input, context: {
kind: string;
name?: string | symbol;
access?: {
get?(): unknown;
set?(value: unknown): void;
};
isPrivate?: boolean;
isStatic?: boolean;
defineMetadata(key: string | symbol | number, value: unknown);
}) => Output | void;
のようになっており、Property Descriptor's Decorators のときの仕様を扱いやすい形式にしたように見える。
その環境下における Intl で対応情報が取得できる API の提案。
code: (js)
for (const calendar of Intl.supportedValuesOf("calendar")) {
// 'buddhist', 'chinese', ... 'islamicc'
}
もともと Temporal 内でこの機能を作ろうとしていたが、Intl で定義しようということで始まった。
Stage 2 になった。
クラスの static 変数やメソッドを static initialization blocks シンタックスを使って定義することが出来るようにする提案。
Stage 2 になった。
Stage 1
Numeric Literal に新たに suffixes を追加する提案。カスタム suffixes も定義できる。
code: (js)
import { Decimal } from "./my-decimal-package.mjs";
with suffix $ = Decimal.literal;
(2.1$).plus(3.2$) // ==> 5.3$
無名なクラスに対して static 変数、メソッドにアクセスできるようにするために class メタプロパティを追加する提案。
code: (js)
class C {
static f() { /*...*/ }
g() {
class.f(); // C.f()
}
}
リサイズ可能な ArrayBuffer として、ResizableArrayBuffer と GrowableSharedArrayBuffer を追加する提案。既に WebAssembly.Memory がリサイズ可能であることや WebGPU で必要にされていることからこの提案が来ている。
code: (js)
class ResizableArrayBuffer {
// Implementable as in-place growth.
constructor(byteLength, maximumByteLength);
// Can throw OOM on both growths and shrinks.
resize(newByteLength);
// Returns a *non*-resizable ArrayBuffer.
slice(start, end);
get maximumByteLength();
get byteLength();
}
class GrowableSharedArrayBuffer {
// Basically must be implemented as in-place growth.
constructor(byteLength, maximumByteLength);
// No shrinking!
grow(newByteLength);
// Returns a *non*-growable SharedArrayBuffer.
slice(start, end);
get maximumByteLength();
get byteLength();
}
ResizableArrayBuffer はデタッチ可能で、GrowableSharedArrayBuffer は不可能という特徴がある。
Moddable, Firefox そして Apple がレビューすることになった。
今まで API を追加するとなるとグローバルオブジェクトに追加してきたが、ネームスペースの節約や初回読み込みのコストを減らす目的で Builtin Modules を追加する提案。
新たに BuiltInModule クラスを追加する話があがっている。
code: (ts)
type ModuleSpecifier = any;
declare class BuiltInModule {
static import(key: ModuleSpecifier): any;
static export(key: ModuleSpecifier, exports: any): void;
static hasModule(key: ModuleSpecifier): boolean;
static freezeModule(key: ModuleSpecifier): void;
static freezeAllModules(): void;
}
これにより例えば shim を用意する場合に
code: (js)
if (!BuiltInModule.hasModule("js:Complex")) {
BuiltInModule.export("js:Complex", { Complex: ComplexPolyfill });
}
のように追加することが出来る。
また IANA に TC39 Register として "js:" を追加するべきか話されている。
TypedArray のコンストラクタを拡張してストライドを扱うことが出来る提案が廃止された。
Template Literal などで文字列を作るときに先頭の空白を除去する方法の提案。新たに3つのバッククオートを使って Template Literal を拡張するか、String.dedent 函数を追加するかの話になっている。
code: (js)
class MyClass {
print() {
console.log(`
create table student(
id int primary key,
name text
)
`)
}
}
Stage 1 になった。
Intl.DisplayNames を拡張して Month, Weekday や TimeZone の文字列を取得する提案。
Stage 1 になった。
ロケールの情報を取得する API を追加する提案。
code: (js)
// Week Data
let weekInfo = Intl.weekInfo("en-US")
// {
// locale: "en-US",
// firstDayOfWeek: 7,
// minimalDaysInFirstWeek: 4,
// weekendStart: 6,
// weekendEnd: 7,
// }
// Text information
let textInfo = Intl.textInfo("ar")
// { direction: "rtl" }
// Defaults
let defaults = Intl.defaults("ja")
// Unit Information
let unitInfo = Intl.unitInfo("ar")
// { measurementSystem: "US" }
Stage 1 になった。
Error のコンストラクタの第二引数として任意のオブジェクトを設定することが出来、Error#cause で取得できるようにする提案。
code: (js)
try {} catch (err) {
throw new Error("Some Error", err);
}
うーん、個人的にはスタックトレースのマージもしてほしいが、それをやりたければ Error Stacks の方の提案でやることになりそう。
Stage 1 になった。
Iterable の Destructring 構文で Ruby や Python のように後ろからも取得できるようにするシンタックスの提案。
code: (js)
Stage 1 になった。
console.log だとその引数の結果が欠如されてしまうので dbg<T>(value: T): T を追加する提案。Ruby における p 函数っぽい。
Stage 1 になった。
Math に Integer や Modulus メソッドを追加する提案。
code: (js)
Math.mod(x, y) // IEEE 754 modulus
Math.idiv(x, y) // Int32 division
Math.imod(x, y) // Int32 modulus
Math.imuldiv(x, y, z) // Int32 multiply and divide with 64-bit intermediate result - (x * y) / z
Math.irem(x, y) // Int32 remainder
Stage 1 になった。
Stage 0
扱われない仮引数を省略できる提案。
code: (js)
function foo( , , baz) {
console.log(baz);
}
まあわからんでもない。
Bind Operators の後釜としての提案。Function#call を使わずに手軽にメソッドとして実行できるシンタックスシュガー。新たに :: 演算子を定義し、それを使うことになる。
code: (js)
// define two extension methods
const ::toArray = function () { return ...this } const ::toSet = function () { return new Set(this) }
// define a extension accessor
const ::allDivs = {
get() { return this.querySelectorAll('div') }
}
// reuse built-in prototype methods and accessors
const ::flatMap = Array.prototype.flatMap
const ::size = Object.getOwnPropertyDescriptor(Set.prototype, 'size')
// Use extension methods and accesors to calculate
// the count of all classes of div element.
let classCount = document::allDivs
::flatMap(e => e.classList::toArray())
::toSet()::size
総括
今回は Intl.DisplayNames が Stage 4 になった。あとはまた結構細かい提案が Stage 1 になった印象がある。