$30 off During Our Annual Pro Sale. View Details »

tc39_study_2

Jxck
July 16, 2021

 tc39_study_2

#tc39_study のスライドです。

動画はこちら
TODO

元 Google Slide はこちら
https://docs.google.com/presentation/d/17znKhpHu__5SBcT0BNIaYHegy4mMs5MWzj59r-qzmeE

Jxck

July 16, 2021
Tweet

More Decks by Jxck

Other Decks in Technology

Transcript

  1. #tc39_study
    https://web-study.connpass.com/event/213676/

    View Slide

  2. 進め方
    ● CFP が通ったらこのスライドに編集権限を付与

    ● 1 テーマ 1 slide のみ作成

    ○ 右上の順番と時間以外は何をどう編集しても OK

    ○ マスタスライドはいじいらない

    ● 当日は主催がこのスライドを画面共有

    ● 自分のターンだけミュートを解除し時間内に発表

    ○ 30s: クリック音 (なくした)

    ○ 3s 前: カウントダウン + ホーン

    ● 時間になったら強制ミュート、すぐ次の人


    View Slide

  3. Pattern Matching (stage 1) - @jxck
    match (res) {
    if (isEmpty(res)) {
    handleEmpty()
    }
    when ({ status: 200, body, ...rest }) {
    handleBody(body, rest)
    }
    when ({ status: 301|302|303|307|308 }) {
    redirect(res)
    }
    when ^ClientError {
    clientError(req)
    }
    else {
    handleError()
    }
    }
    No1: 90s
    class ClientError {
    static [Symbol.matcher](status) {
    if (400 <= status && status <= 499) {
    return {
    matched: true
    }
    }
    }
    }
    matching clause
    or combinator
    match expression
    record / tuple などと組み
    合わせるとさらに強力にな
    りそう。

    View Slide

  4. proposal-do-expression(@sadnessOjisan)
    ● 何をするか: (中に文を書ける)do ブロックから値を返す↩
    ● 嬉しいこと: 式指向プログラミングが実現しやすくなる
    👉 これまでは即時関数で頑張っていた
    👉 function(){if(){return}else{return}}()
    ● 具体的なユースケース🔧
    ○ 局所変数: ある値を作るための一時変数が定義しやすい
    ○ if式: 条件節やネストが複雑な 3項演算子は見にくい(と主張する人もいる)
    ● 特にTS + Reactとの相性の良さに期待している 😘
    ○ 再レンダリングを気にせずに分岐を書ける(かもしれない)
    ■ これまでは分岐ロジックを return の外に書くと、コンポーネントの粒度に
    よっては再レンダリングの範囲が大きくなる
    ○ if や switch での分岐漏れを JSX 内から assertNever と呼ばれるテクニックで防
    げる(かもしれない)
    ■ これまでは 3項演算子を利用していたが、 3項演算子では assertNever
    できない
    No2: 90s
    babel や babel-preset-react ですでにサポートされている.実
    装例: https://github.com/sadnessOjisan/do-playground
    const f = () => 3;
    let x = do {
    let tmp = f();
    tmp * tmp + 1;
    };
    const Component = (props) => (

    {do {
    if (props.color === "blue") {
    blue ;
    } else if (props.color === "red") {
    red ;
    } else if (props.color === "blue") {
    blue ;
    } else {
    // assertNever とかができる!
    }
    }}

    );

    View Slide

  5. Records & Tuples (Stage 2)
    ● https://github.com/tc39/proposal-record-tuple
    ● 再帰的イミュータブルな Object, Array欲しくない?
    ● こう書きたい
    ○ #{ x: 1, y: 2} // こっちが Record
    ○ #[1, 2, 3, 4] // こっちが Tuple
    ● 何ができる
    ○ Record, TupleはプリミティブかRecord, Tupleしか含められない
    (String, Number, Boolean, undefined, null, Symbol, BigInt)
    ○ Recordはドットアクセス、Tupleはインデックスアクセスできる
    ○ 内容で比較できる
    ■ #{ x: 1 } === #{ x: 1 } // true
    ■ #[0, 1, 2] === #[0, 1, 2] // true
    ○ Array.from()使える、Object.keys()も使えるようにしたい
    ○ Tuple.from()、Record.fromEntries()を作る案もある
    No3: 90s
    @okunokentaro

    View Slide

  6. Observable - Stage 1
    ● 「川の上流からモノを流す => 下流のどこかでモノを受け取り、処理する」が簡便に
    書ける
    ○ 上流 = Observable, モノ = 任意の値, 流す = next(), 下流のどこか = subscribe()
    No4: 90s
    // 1,2,3の値を流したのち、 1000ミリ秒後に4を流して完了する Observable
    const observable = new Observable(subscriber => {
    subscriber.next(1);
    subscriber.next(2);
    subscriber.next(3);
    setTimeout(() => {
    subscriber.next(4);
    subscriber.complete();
    }, 1000);
    });
    console.log('==== just before subscribe ====');
    observable.subscribe({
    next(x) { console.log(`got value ${x}`); },
    error(err) { console.error(`something wrong occurred: ${err}`); },
    complete() { console.log('done!!!'); }
    });
    console.log('==== just after subscribe ====');
    ==== just before subscribe ====
    got value 1
    got value 2
    got value 3
    ==== just after subscribe ====
    got value 4
    done!!!

    View Slide

  7. const RGBOps = Operators(
    {
    "+"(a, b) {
    // エラーハンドリングは省略している雑な実装
    return {
    r: a.r + b.r,
    g: a.g + b.g,
    b: a.b + b.b,
    };
    },
    },
    {
    right: Number,
    "*"(a, b) {
    return { r: a.r * b, g: a.g * b, b: a.b * b };
    },
    }
    );
    class RGB extends RGBOps {
    r; g; b;
    constructor(hex) {
    this.r = parseInt(hex.slice(1, 3), 16);
    this.g = parseInt(hex.slice(3, 5), 16);
    this.b = parseInt(hex.slice(5, 7), 16);
    }
    }
    new RGB("#A1B2C3") + new RGB("#1A2B3C"); // Error。
    with operators from RGB;
    new RGB("#A1B2C3") + new RGB("#1A2B3C"); // new RGB('#BBDDFF')
    No5: 90s
    Operator overloading (Stage 1) @arayaryoma
    Operator setの定義
    “+”: RGBの各要素を加算する
    factory関数に定義を渡すと
    classが返ってくる
    “*” の右がNumber型だった場合の定義
    RGBの各要素をN倍する
    RGB class に対して定義したOperator setを
    有効にする
    Operators()から返ってきたclassを継承する
    with operators from RGB で利用を宣言
    @use: operators も検討されているっぽい
    Initial commit: 2018/12/19
    Latest commit: 2021/1/5
    Champion: @littledan
    https://github.com/tc39/proposal-operator-ov
    erloading
    use cases
    ● 複素数
    ● ベクトル・行列
    ● CSSの単位(emなど)

    View Slide

  8. Decorators - stage 2
    ● 関数・クラスを置き換えたり、メタデータを付
    加したりできる機能
    ○ 例えば、関数の前後にログ出力を挿入したり
    ○ 関数の前後でローディングを回してみたり
    ○ 関数をイベントハンドラーにしたり
    ○ クラスのメタデータをベースに DI してみたり etc
    ● 強力な機能ゆえに問題が多く、過去3度白紙
    に戻っている。
    ● 現在は4つ目のプロポーザル (simplified
    decorators) が策定中。過去のプロポーザル
    に比べて、runtime の perf penalty が少な
    い、traspile が簡単な事などが特徴
    ● Babel の実装が固まり次第 Stage 3 にアプ
    ライされる予定 (来年ぐらい?)
    No6: 90s
    Champion
    Chris Garrett

    View Slide

  9. Deferring Module Evaluation (@kaa_a_zu )
    ● ESModules によって モジュールは即座に実行されるようになった
    ● 1.読み込み 2.解析 3.評価 を即座に行うことのパフォーマンスは悪い
    ● コストの問題を解決するため `import()` が使われているが、これは中のコード
    全てを非同期
    に実行してしまう
    ○ 1)リファクタリングのコストが高くなる
    ○ 2)読み込むモジュールの競合が発生する可能性がある
    ● 3つの延期タイミング候補 ①Before Load ②Before Parse ③Before Evaluate
    ○ Before Load 遅延は `import()` が行っている
    ○ Before Parse 遅延は モジュール・グラフが存在しなくなるのでやめたい
    ○ Before Eval 遅延は `import()` と組み合わせることで 起動時のI/Oコスト, 初期化コストを削減できる
    No7: 90s
    #Stage1 #パフォーマンス #モジュール評価遅延
    /* import attribute方式 (stage3 import-assertion の将来)
    */
    import {x} from "y" with { lazyInit: true }
    /* カスタムキーワード方式 */
    lazy import {x} from "y";

    View Slide

  10. Module Fragments (@__sosukesuzuki)
    ● Stage 1
    ● モジュールをインラインで記述するための文を導入する
    ● プログラマは複数のファイルにそれぞれモジュールを書く
    ● Native ESM として実行するとモジュールごとにfetchするのでパフォーマンス上の
    懸念がある
    ● 現代ではバンドルするのが主流だがバンドラの実装コストが高くモジュール構造が
    ランタイムまで残らず最適化に使うことができない
    ● 1ファイルに複数のモジュールをバンドラから出力できればそれらの問題を解消で
    きる
    ● module “#foo” { export const foo = “foo”; } みたいな構文
    ○ (少なくとも Stage 1 になったタイミングでは )
    No8: 60s

    View Slide

  11. 🚨 proposal-error-cause @_keiya01
    ● Stage 3
    ● これまでは Error コンストラクタを拡張す
    る必要があった
    ● Developer Tool などのツールでエラー
    の連鎖を扱い難い
    ● この仕様により DevTool などのツール
    で Error の連鎖が見やすくなる
    No9: 60s
    https://github.com/tc39/proposal-error-cause
    https://twitter.com/FirefoxDevTools/status/1414965543593988104

    View Slide

  12. Import Assertions (@takanorip)
    ● インポートするモジュールについてキータイプを明記、インポート時に正しいタイプのファイル
    がインポートされているか検証する仕組み
    ● ウェブ上ではファイル拡張子と HTTP Content Typeヘッダーの間には、広くミスマッチが存在
    するため、サーバーが予期せず異なる MIMEタイプを提供し予期せずコードが実行されてしま
    うことを防ぐことが目的
    ● 現在はJSON Modulesだけが提案されてるが、 HTML ModulesやCSS Modulesも議論中
    No10: 60s

    View Slide

  13. standard libs can be loaded
    using import syntax.
    - import common way
    - import() dynamic async
    - importNow() sync for script
    Built In Modules aka JavaScript Standard Library
    (@yosuke_furukawa)
    No11: 60s
    Motivation Solution
    Import Semantics Contents
    No More !! Global property !!!
    - window
    - global
    Run Anywhere
    - Browser/Node/etc
    Namespace: `js:` reserved.
    - IANA register
    Module Freeze:
    - Object unextendable
    - enforce Object.freeze
    本日の和気あいあいスレ
    https://github.com/tc39/proposal-
    built-in-modules/issues/16
    - URL
    - Array / Set / etc
    - 個人的に欲しい: LinkedList,
    BinaryHeap, collection

    View Slide

  14. ユーザーによる 非同期処理の制御 が可能な protocol を定義
    Cancellation API
    No12: 60s
    @progfay
    Stage 1
    AbortController Cancellation API
    WHATWG DOM Standard
    EventTarget を用いた実装
    AbortSignal と 1 対 1 対応 (派生なし)
    主要ブラウザ、 Node.js で利用可能
    TC39 Stage 1 (Last update: July 2018)
    Callback を用いた実装
    派生先にもキャンセルが伝播する
    参考実装あり (npm install prex)
    AbortController.follow() の提案あり

    View Slide

  15. Collection {coerceKey, coerceValue} - Stage 2
    ● Map のキーと値、Set のキーに
    アクセスする際にそれらを
    変換する手段を提供
    ● Map と Set のコンストラクタの
    第 2 引数を追加
    ● URLSearchParams、Header、
    DomStringMap等の既存
    ユースケースの実現を容易に
    No13: 60s
    https://github.com/tc39/proposal-collection-normalization
    const map = new Map([], {
    coerceKey: String
    });
    // stored using { [[Key]]: "1", [[Value]]: "one" } in map.[[MapData]]
    map.set(1, 'one');
    // looks for corresponding { [[Key]]: "1" } in map.[[MapData]]
    map.has(1); // true
    // functions directly exposing the underlying entry list are unaffected
    [...map.entries()]; // [["1", "one"]]
    const set = new Set([], {coerceValue: JSON.stringify});
    // stored using { [[Value]]: '{"path": "/foo"}' } in set.[[SetData]]
    set.add({path: '/foo'});
    // looks for corresponding { [[Value]]: '{"path": "/foo"}' } in set.[[SetData]]
    set.has({path: '/foo')};
    // functions directly exposing the underlying entry list are unaffected
    [...set]; // ['{"path": "/foo"}']

    View Slide

  16. ● https://github.com/tc39/proposal-decimal
    ● 0.1 * 0.2 === 0.020000000000000004 // true
    ○ IEEE754 倍精度浮動小数点数がどうのこうの(割愛)
    ● JavaScript環境下での金額計算といった 10進数計算の正確さが
    従来より求められるようになった
    ○ Numberのままの実装は税率計算などでミスが起こる
    ○ ライブラリの導入をせざるを得ない
    ● typeof 1m === "bigdecimal" // true
    ○ BigIntのようにリテラルは数値mで表現(例:1m, 234.56m)
    ○ decimalのdじゃないの?
    ■ 16進数表現の文字にdが含まれるから避けたい
    ● リテラルでない表記、 Number値からの変換はBigDecimal(num)
    ○ プリミティブの扱い、 new不要
    No14: 60s
    @okunokentaro
    Decimal (Stage 1)

    View Slide

  17. JSON modules (@takanorip)
    ● import assertionsをベースにJSONモジュールをインポートできるようにする仕組み
    ● もともとimport assertionsの一部だったが、2020年7月に分割された
    ● TC39でJSONモジュールを定義することで ECMA262に準拠したすべてのホストで一貫した動
    作が保証される
    ● JSONモジュールにアサーションが必要かどうかはホスト( Node.jsなど)が決定する
    No15: 60s

    View Slide

  18. 🧳 proposal-js-module-blocks @_keiya01
    ● Stage 2
    ● WorkerやWorkletのモジュールを別ファ
    イルに切り出さなければならないのは不
    便
    ● モジュールをインラインで書くことができ

    ● Module Blocks を参照することはできな

    ● structured cloneable
    No16: 60s
    https://github.com/tc39/proposal-js-module-blocks

    View Slide

  19. proposal-pipeline-operator No17: 60s
    @maxmellon
    stage-1
    概要
    備考 : 現在 pipeline に2つの style の提案が存在
    ● F# style
    ● Hack Style
    F#, Elixer など 様々な言語にあるものに似たオペレーターを JavaScript にも
    左辺の評価値を右辺の関数に適用するアレ
    partial-application-proposal と組み合わせるとより最高
    > アローファンクションなしに,部分適用できるので便利
    何が嬉しいの?
    .pipe(), pipe(), pipeP(), flow(), compose() で消耗したくない
    Mix-in と
    組み合わせるのもアリ
    自分は F# style のほうが好み
    Babel の実装があるので試すのおすすめ

    View Slide

  20. Limited ArrayBuffer (@Tsubame_misa)
    Stage1 ArrayButterを読み込み専用にしたり,一部分だけ読み書き可能にしたい
    デザインゴール
    ● ArrayBufferをfreezeする
    ○ 読み取り専用になる
    ○ TypedArray/DataViewも読み取り専用になる
    ● 読み取り専用のTypedArray/DataViewから書き込みに変換できないようにする
    ● 小さな選択範囲から大きな範囲を読み込み書き込みできないようにする
    ● 実装者にあまり複雑さを与えないように
    嬉しい
    ● 最小限のpermission/infomationの原則をArrayBuffer上で動かせる
    ● Embedded JS enginesでROMを読み取り専用のArrayBufferとして表せる
    No18: 60s
    https://github.com/tc39/proposal-limited-arraybuffer

    View Slide

  21. Accessible Object.prototype.hasOwnProperty - Stage 3
    ● Object.prototype.hasOwnProperty をシンプルに書けるような、.hasOwn() の追加
    ● hasOwnProperty は、Object が引数と同じ property を持っているかを返す
    ○ 「hasOwnProperty」という名称は、保護されていないので上書きが可能 😢
    No19: 60s
    // before
    const obj = {foo: 'hoge'};
    if (Object.prototype.hasOwnProperty.call(obj, 'foo')) {
    console.log('has property foo');
    };
    // after
    const obj = {foo: 'hoge'};
    if (Object.hasOwn(obj, 'foo')) {
    console.log('has property foo');
    };
    // hasOwnProperty を上書きする例
    const foo = {
    hasOwnProperty: (p) => {
    return false;
    },
    bar: 'Here be dragons'
    };
    foo.hasOwnProperty('bar'); // => 常に false を返してしまう
    ({}).hasOwnProperty.call(foo, 'bar'); // => true
    Object.prototype.hasOwnProperty.call(foo, 'bar'); // => true

    View Slide

  22. Partial Application Syntax - Stage 2
    ● 関数の部分適用を導入
    ● ? プレースホルダによる構文
    ● 関数、アロー関数、テンプレート文字列
    を対象
    ● パイプライン演算との併用可
    function add(x, y) { return x + y; }
    // Function#bind
    const addOne = add.bind(null, 1);
    addOne(2); // 3
    // arrow functions
    const addTen = x => add(x, 10);
    addTen(2); // 12
    // arrow functions and pipeline
    const newScore = player.score
    |> _ => add(7, _)
    |> _ => clamp(0, 100, _);
    const addOne = add(1, ?); // apply from the left
    addOne(2); // 3
    const addTen = add(?, 10); // apply from the right
    addTen(2); // 12
    // with pipeline
    let newScore = player.score
    |> add(7, ?)
    |> clamp(0, 100, ?);
    No20: 60s
    https://github.com/tc39/proposal-partial-application

    View Slide

  23. Realms (@takanorip)
    Realmオブジェクト内でJSを仮想化、実行できる仕組み

    ● WebベースのIDE
    ● testing/mocking
    ● ウェブ用のプラグイン(例:スプレッドシート関数)
    ● サーバーサイドレンダリング
    ● in-browser transpilation
    No21: 60s

    View Slide

  24. Temporal - stage3 (@sititou70)
    ● Dateの欠点を克服するdate / time API
    ○ 現状のDateオブジェクトは1995年の「java.util.Date」の一部がもとになっている
    ○ もとになったAPIは(Temporalの中の人,@maggiepint氏曰く)率直に言って ひどいらしい
    ■ 実際,1997年のJava 1.1で非推奨になっている
    ● UTCオフセット / タイムゾーンのフルサポート
    ● 日時の明確な文字列表現
    ○ →日付を曖昧に解釈・計算してしまうことによるバグを軽減
    ● 他にも:イミュータブル,グレゴリオ暦以外のカレンダーのサポート
    ● (私見)既存の日付ライブラリと比較して
    ○ Temporalは,タイムゾーン / オフセットを書き手にしっかり意識して書かせる印象(健全)
    ○ 既存の「あまりタイムゾーン等を意識していないコード」を移植するのは少し大変?
    No22: 60s

    View Slide

  25. Dynamic Import Host Adjustment (@shisama_)
    ❏ 概要
    ❏ Trusted Typesと相互運用性を持つための Proposal
    ❏ Trusted Typesとは?
    ❏ DOM-based XSSを防ぐためのブラウザのセキュリティ機能
    ❏ Sinkへ代入する時にSourceの文字列を安全な型へ変換することを強制する
    ❏ Trusted Typesの問題
    ❏ import()のモジュール指定子は文字列しか受け取れない仕様のため安全な型を強制できない
    ❏ Dynamic ImportはTC39の持ち物なのでWebの都合だけでは仕様を変更は難しそう
    No23: 60s
    // import()にtoString関数を含むオブジェクトを渡す
    const m = import({
    toString() {
    console.log('ホストは任意の処理が可能
    ');
    return trustedModule;
    },
    });
    m.then(() => console.log('module resolved'
    ))
    ❏ このProposalでできること
    ❏ import()にtoString関数を含むオブジェクトを渡す
    ❏ toString内では、ホスト(ブラウザに限らない)は
    モジュール指定子の検査・調整など任意の処理
    が行える
    Stage 2

    View Slide

  26. No24: 60s
    ➢ Promiseを返すAtomics.wait()
    ➢ 内部的には,waiterListにAgentを追加する処理
    を,新しい関数であるdoWait()でラップ
    ➢ これまで同期的に待つ必要があった
    Atomics.wait()をpromise-baseに書ける.

    Atomics.waitAsync() - @you_5805

    View Slide

  27. proposal-readonly-collections (@sadnessOjisan)
    No25: 30s
    https://github.com/tc39/agendas/blob/master/2019/
    10.readonly-collections-as-recorded.pdf
    ES3 everything mutable
    ES6 all collections mutable
    class AbstractMap {
    // A FixedMap, not necessarily fresh, whose state is this map's current
    // state.
    snapshot() :FixedMap;
    // A fresh Map whose initial state is this map's current state.
    diverge() :Map;
    // A ReadOnlyMap, not necessarily fresh, whose state is a read only
    // view of this map's current state.
    readOnlyView() :ReadOnlyMap();
    // query-only methods of Map
    ...
    }
    マスタの管理とかがしやすくなるよ!
    ReadOnlyMap, FixedMap
    例としてMap

    View Slide

  28. Grouped Accessors and Auto-Accessors for ECMAScript(@kumastry)
    Grouped Accessors
    セッターとゲッターをグループ化したもの
    何が嬉しい❓ ❓ ❓ ❓ ❓                      
    ・読みやすくなる
    Auto-Accessors
    Group Accessorsを簡略化したもの
    フィールドのアクセス権も初期化可能
    何が嬉しい❓ ❓ ❓ ❓ ❓
    ・フィールドのイミュータブル設定が簡単
    ・ゲッターとセッター使わなくてもアクセス可能
    No26: 30s
    https://github.com/rbuckton/proposal-grouped-and-auto-accessors

    View Slide

  29. Set and Map .of and .from (@oliver_diary)
    No27: 30s
    `Array.of` や `Array.from` のような
    メソッドをSetとMapにも追加する提案
    元々のモチベーションは右のような形であったが、
    `Array(0)` や `Array(0,1)`などのoverloadによって引数
    の意味が異なるのが懸念点としてあるので `of`, `from` を
    追加するのが良いのでは?という形になった
    ● 具体的にはCollectionCreateという抽象操作(abstract operation)を追加し、それぞれのメソッド内で
    呼び出すことでiterationを可能にしている
    ● WeakSetやWeakMapにofやfromを追加する提案も同時にされている
    Stage1

    View Slide

  30. Export Default From (@Shinyaigeek 🐵)
    ● default export されているものをnamed exportし直すことができる
    No28: 30s
    ● この書き方と同義, 新しいuse caseをカバーするものというよりはより自然な文法を
    提供するもの
    https://github.com/tc39/proposal-export-default-from
    ● [[ExportName]] は default ではなく name

    View Slide

  31. async do expressions (@yoshiko_pg) Stage 1
    ● Stage1のdo expressionsにasyncをつけることで、新しい非同期コンテキストを生成でき
    る提案
    ● 通常のdo expressionsの中でawaitすると、doの外側のcontextがblockingされる
    ● async do expressionsの中でawaitすると、doの外側のcontextはblockingされない
    No29: 30s

    View Slide

  32. WHATWG URL (@Tsubame_misa)
    Stage 0
    ● WHATGW の URL, URLSearchParamsを ECMAScriptの仕様に導入したい
    ● Web以外でも動いて嬉しい
    No30: 30s
    https://github.com/jasnell/proposal-url

    View Slide

  33. No31: 30s
    Slice notation (Stage 1) @arayaryoma
    const array = ["a", "b", "c", "d"];
    array.slice(1, 3); // => ['b', 'c']
    array.slice(3); // => ['d']
    array.slice(-2); // => ['c', 'd']
    // array.slice(1, 3)と同等
    array[1:3] // => ['b', 'c']
    // array.slice(0, 3)と同等
    array[:3]; // => ['a', 'b', 'c']
    // array.slice(1)と同等
    array[1:]; // => ['b', 'c', 'd']
    // コピーが作られる。 array.slice()と同等
    array[:]; // => ['a', 'b', 'c', 'd']
    // array.slice(-2)と同等
    array[-2:]; // => ['c', 'd']
    // array.slice(0, -10) と同等
    array[:-10]; // => []
    Initial commit: 2018/5/2
    Latest commit: 2020/7/12
    Champion: @gsathya
    https://github.com/tc39/proposal-slice-notati
    on
    Array.prototype.slice
    引数が1つのときの挙動が
    分かりづらくない?
    新しい記法の提案
    対応表:
    ● a[n:m] ⇔ a.slice(n, m)
    ● a[n:] ⇔ a.slice(n)
    ● a[:m] ⇔ a.slice(0, m)
    ● a[:] ⇔ a.slice()

    View Slide

  34. Array Equality - Stage 1
    ● 配列の「要素の値」が等しいかを返す .equals() の追加
    ○ 単純な比較では、配列の参照元(アドレス)を比較してしまい、狙った挙動にならない 😢
    No32: 30s
    [1, 2, 3].equals([1, 2, 3]); // => true
    [1, 2, undefined].equals([1, 2, 3]); // => false
    [1, [2, [3, 4]] ].equals([1, [2, [3, 4]] ]); // => true
    const a = [
    {foo: 'bar'},
    {foo: 'baz'}
    ];
    const b = [
    {foo: 'bar'}
    ];
    a.equals(b); // => false

    View Slide

  35. ● Stage1
    ● このproposalで追加されるArray.prototype.filterRejectはコールバック関数で実装
    されたテストに不合格だったすべての要素からなる新しい配列を生成する
    ● Array.prototype.filter()はコールバック関数で実装されたテストに合格したすべての
    要素からなる新しい配列を生成する
    ● 類似するメソッドとして、RubyにArray#reject、Underscoreに_.reject、Lodashに
    _.rejectや_.partitionがある
    No33: 30s
    proposal-array-filtering (Forest_Y)

    View Slide

  36. 現状での再現方法: [...arr].reverse().find()
    array-find-from-last
    No34: 30s
    @progfay
    Stage 2
    Array.prototype.findLast(), Array.prototype.findLastIndex() を追加
    ● 不必要なパフォーマンスの低下を招く
    ● index を取得したい場合には不便
    不要なcopy 不要なmutation

    View Slide

  37. Array.prototype.uniqueBy() (@autummn_fish)

    ● Stage1

    ● 重複する要素を削除した新しい配列を返すメソッド

    ● 非プリミティブ型に対応した[...new Set(array)]を返す

    ● 引数としてNumber,String,Symbolを指定可能

    ○ 引数をkeyとして重複要素の削除を行う

    ● 関数を引数として渡せる

    ○ 配列の各要素ごとに関数を呼び出し、関数の戻り値に基づいて重複要素を削除する 

    ● 0と-0の区別はない

    ● 空、もしはNullishな値の場合Nullishとして扱われる

    ● NaNは区別されない

    No35: 30s

    View Slide

  38. No36: 30s
    @okunokentaro
    ● https://github.com/jasnell/proposal-deprecated
    ● JSDoc @deprecated
    ○ これをセマンティックにしたい
    ● 2つのやり方が考えられる
    ○ deprecated global
    ○ 'deprecated' pragma
    ● pragmaだと理由とか書けそうだよね
    ○ 'deprecated; This is deprecated, use something else'
    Deprecated (stage 0)

    View Slide

  39. await.ops (@__sosukesuzuki)
    ● Stage 1
    ● await Promise.(all/race/any/allSettled) promises という形はよく使われる
    ● が、微妙に記述量が多くだるい
    ○ await Promise.all(hoges.map((hoge) => someOperation(hoge)));
    ● 短く簡単に書きたい
    ● await.(all/race/any/allSettled) promises
    ○ await.all hoges.map((hoge) => someOperation(hoge));
    ● カッコが減るとうれしい
    ● 余談
    ○ https://github.com/sosukesuzuki/babel/pull/4
    ○ で Babel に実装をしている最中です
    No37: 60s

    View Slide

  40. モチベーション
    ➢ ある非同期関数の呼び出しで,実際に処理が行われる
    のが同期処理のみである場合,これをタスクキューでは
    なく即座にコールスタックに追加したい
    ➢ 下7行目でも可能だが直感的でない
    アプローチ
    ➢ Promise.try(f)でこれを達成
    No38: 30s

    Promise.try() - @you_5805

    View Slide

  41. Deep Path Properties in Record Literals (@yoshiko_pg)
    ● Stage2のRecords & TuplesのRecordを前提としたProposal
    ● RecordにネストしたRecordのkeyを表現するときに . を使える
    ● RecordにネストしたTupleのindexを表現するときに [] を使える
    ● Objectへの追加は提案していない。 immutableであることを前提とした提案
    ● 存在しない箇所にアクセスしたら TypeError。 ?で無効化する提案がissueに出ている↓
    ● ↓既存のRecordを元に新しいRecordを作成するbefore/after
    No39: 30s
    before(現在)
    after

    View Slide

  42. Function.isCallable() / Function.isConstructor() - Stage 0
    ● Function.isCallable( argument )
    1. If IsCallable(argument) is false, return false.
    2. If argument has a [[isClassConstructor]] internal slot with value true, return false.
    3. Return true.
    ● Function.isConstructor( argument )
    1. Return IsConstructor(argument).
    ● IsCallable, IsConstructor: ECMAScript SpecificationのAbstract Operations
    No40: 30s
    https://github.com/caitp/TC39-Proposals/blob/HEAD/tc39-reflect-isconstructor-iscallable.md

    View Slide

  43. Class brand check (@kumastry)
    一言で言うと instanceof のstaticメゾット版
    他のクラスベースのOOPプログラミング言語と同様のコンセプトモデルを提供する
    class.hasInstance(o) ⇔ o instanceof class
    classにはclass名,oにはインスタンスが入る
    乙 \(・。・?)/
    No41: 30s
    https://github.com/tc39/proposal-class-brand-check

    View Slide

  44. Generator function.sent Meta Property (@Shinyaigeek 🐵)
    ● Generator関数の中で利用できるメタプロパティ
    No42: 30s
    ● yieldを呼べるところでならどこででも参照できる
    ● 直近で呼ばれたgenerator objectのnext関
    数の引数を取得できる
    ● Generator関数の構造上, 最初に呼ばれるnext関
    数の引数にアクセスする方法がない問題に対応し
    ている
    https://github.com/tc39/proposal-function.sent

    View Slide

  45. Generator Arrow Functions (@oliver_diary)
    No43: 30s
    ● generator構文をArrow functionsに追加する提案と `generator` キーワードを追加し
    `ASI hazard` を避ける提案の2つが上がっている。
    ● 現在はArrow functionsのどこにアスタリスクを付けるかに議論が集中しているが、
    `() =*>` に軍配が上がりそうな感じではある。
    generatorキーワードの提案 アスタリスク記法の候補 現状の有力候補
    Stage1

    View Slide

  46. 🙈 proposal-private-fields-in-in @_keiya01
    ● Stage 4
    ● 指定した Private Field を持っているか
    どうかをチェックしたい
    ● `try {} catch {}` を使えばできるが、
    余計な例外もキャッチしてしまう
    ● `in` キーワードを使って指定された
    Private Fieldを持っているかどうかを判
    定できる
    No44: 30s
    https://github.com/tc39/proposal-private-fields-in-in

    View Slide

  47. ● Stage1
    ● Array.prototypeもしくはTypedArray.prototypeに対して変更を行うメソッドを追加す
    るproposalになる
    ● 類似する既存のメソッドでは対象となるArray(TypedArray)に対して破壊的に変更
    されるのに対し、追加されるメソッドでは対象となるArray(TypedArray)に対し非破
    壊的に変更を行う
    ● 対象メソッドはArray.prototype.fill(value, start, end)やArray.prototype.pop()など
    の全10種類
    No45: 30s
    Change Array by copy (Forest_Y)

    View Slide

  48. Iterator Helpers (@shisama_)
    ● IteratorとAsyncIteratorに.map()や.filter()などの
    便利メソッドを生やすProposal
    ● IteratorをArrayのように扱うためのライブラリはす
    でにある
    itertools, lodash, ix...etc
    ● Rust、Python、C#ではIteratorで便利メソッドを使
    うことができる
    ● 現在提案されているのは...
    .map() .filter() .take() .drop()
    .asIndexedPairs() .flatMap() .reduce()
    .toArray() .forEach() .some() .every() .find()
    .from()
    No46: 30s
    function* naturals() {
    let i = 0;
    while (true) {
    yield i;
    i += 1;
    }
    }
    const result = naturals()
    .filter(value => {
    return value % 2 == 0;
    });
    result.next(); // {value: 0, done: false};
    result.next(); // {value: 2, done: false};
    result.next(); // {value: 4, done: false};
    Stage 2

    View Slide

  49. Array.prototype.at() (@autummn_fish)

    ● Stage3
    ● 負の添字を指定した場合、配列末尾から
    N番目の要素を返すメソッド
    ○ Pythonのように添字を扱えてうれしい
    ○ 現状ではarr[arr.length-N]のように記述できるが冗長だし匿名の値の場合一時変数を用意しなければならない
    ○ arr.slice(-N)[0]としても記述可能だが、新しい配列を作成してしまう
    No47: 30s

    View Slide

  50. Symbols as WeakMap keys (@nkowne63)
    ● Stage 2
    ● Symbolを新たにWeakMapのkeyとして利用できるようにするProposal
    ● 今まではWeakMapを使うために適当なオブジェクトを生成するなどの必要があっ
    たが、そんなことをしなくてもWeakMapが使えるようになる
    ● そもそもWeakMapはGCをするためにkeyをuniqueにする必要があるのだが、
    Symbolは基本的にuniqueということで提案されている。
    ● 実際は、Symbol.forといった(直接共有されていなくても)取得可能なSymbolがあ
    る(つまり、GCできないものがある)ため、どうするかは議論中とのこと。
    No48: 30s

    View Slide

  51. New Set methods (@mignon8) No49: 30s
    methods
    例:A.intersection(B)
    return values
    Set.prototype.intersection() A∩B (共通集合/積集合) AとB両方に入っている要素の集合を返す
    Set.prototype.union() A∪B (和集合) AとBの、片方または両方に入っている要素の集合を返す
    Set.prototype.difference() A\B (差集合) Aの中から、Bに属する要素を取り去った集合を返す
    Set.prototype.symmetricDifference() (A\B)∪(B\A) (対称差) AとBの、片方にだけ属する要素からなる集合を返す
    Set.prototype.isSubsetOf() A⊆B (部分集合)の真偽 Aが、Bの一部の要素だけからなる集合か否かの真偽値を返す
    Set.prototype.isSupersetOf() A⊇B (部分集合)の真偽 Bが、Aの一部の要素だけからなる集合か否かの真偽値を返す
    Set.prototype.isDisjointFrom() A∩B=Φ(空集合)の真偽 AとBの共通集合が、空集合か否かの真偽値を返す
    ・このproposalには含まれていないが、検討の価値ありとされているクラスメソッドもある
     Set.union(...iterables)
     Set.intersection(...iterables)
    ※引数はiterable
    https://github.com/tc39/proposal-set-methods

    View Slide

  52. 嬉嬉












    嬉 嬉




    嬉嬉












    嬉 嬉




    嬉嬉












    嬉 嬉




    No50: 30s
    #tc39_study / @TakumaNitori
    ECMAScript Module (ESM)
    CommonJS Module (CJS) ♥ 明確なスコープ
    ♥ 不要な as 改名を撲滅
    ♥ 起動時のオーバーヘッド削減
    ♥ impo エラーがブロック内完結
    ♥ if / switch で読ませない選択肢
    ♥ try catch できる
    〜 嬉しいポイント 〜




















    Stage: 0 / Nested impo declarations
    Stage: 0 / Nested impo declarations
    ECMAScript Proposal: Nested import declarations (https://github.com/benjamn/reify/blob/HEAD/PROPOSAL.md)
    【公式】 ダーリンダンス/かいりきベア feat.初音ミク (https://www.youtube.com/watch?v=Rkrm5foi188&t=55s)
    スコープ
    呼び出し箇所
    import 名

    View Slide

  53. Math Extensions
    No51: 30s
    @progfay
    Stage 1
    Math.clamp(x, lower, upper): xを[lower, upper]の区間で丸めた値を返す
    upper
    lower
    x1 x2 x3
    ret1 ret2 ret3
    Math.scale(x, inLow, inHigh, outLow, outHigh):
    xを[inLow, inHigh]から[outLow, outHigh]にマッピングした値を返す
    x
    ret
    in
    out
    Math.RAD_PER_DEG ⇄ Math.DEG_PER_RAD Math.radians(deg) ⇄ Math.degrees(rad)

    View Slide

  54. proposal-string-dedent (@sadnessOjisan)
    No52: 30s


    class MyClass {
    print() {
    console.log(`create table student(
    id int primary key
    name text
    )`)
    }
    }
    class MyClass {
    print() {
    console.log(`
    create table student(
    id int primary key
    name text
    )
    `)
    }
    }
    class MyClass {
    print() {
    console.log(```
    create table student(
    id int primary key,
    name text
    )
    ```)
    }
    }

    View Slide

  55. Upsert (@Shinyaigeek 🐵)
    ● Update + Insert
    No53: 30s
    ● Mapに(key, value)を追加する際, 既にkeyが
    登録されている時(update)とされていない時
    (insert)の処理をかける
    ● insert, updateは省略可能であり, 省略された
    時は何もしない.
    https://github.com/tc39/proposal-upsert
    ● しかしinsertが省略されていてかつkeyがMapに
    登録されていないときはRuntimeErrorになる

    View Slide

  56. No54: 30s
    throw expression (Stage 2) @arayaryoma
    // throw statement
    function hello(name) {
    if (name === undefined) {
    throw new Error("arg: name must be passed");
    }
    console.log(`Hello, ${name}`);
    }
    // throw expression
    function hello(name = throw new Error("arg: name must be passed")) {
    console.log(`Hello, ${name}`);
    }
    hello(); // Error 'arg: name must be passed'
    // throw statement
    const result = obj?.a?.b;
    if (result === undefined || result === null) {
    throw new Error("obj.a.b is undefined");
    }
    // throw expression
    const result2 = obj?.a?.b ?? throw new Error("obj.a.b is undefined");
    Initial commit: 2017/7/16
    Latest commit: 2018/1/24
    Champion: @rbuckton
    https://github.com/tc39/proposal-slice-notati
    on
    throw を式で書ける
    関数のデフォルト値として定義したり
    ?. や ?? と組み合わせると便利
    引数がなかったら throwする
    プロパティがなかったら throwする

    View Slide

  57. JavaScript standard library UUID (@oliver_diary)
    ● 標準ライブラリとしてRFC 4122に基づいたUUIDを提供する提案
    ● npmのuuidモジュールがとても多く使われてる現状と、 RFC 4122に触れたことのない開発者が 車輪
    の再発明をした際に衝突のリスクがある観点から、標準化することで
    「CSPRNG」と呼ばれる「暗号論的擬似乱数生成器」を強制することができるのがモチベーションとし
    てある。
    No55: 30s
    提案されているAPI
    (crypto interface に追加パターン)
    他に考えられる選択肢
    (メソッドをグローバルに公開パターン
    )
    crypto名前空間に含めることでCSPRNGを使用してUUIDを生成するという
    要件を強調している
    Stage1

    View Slide

  58. Seeded Pseudo-Random Numbers (@Tsubame_misa)
    stage 1 再現可能なランダム値を生成できるようにしたい
    ● PRNGの作成:Math.seededRandoms()
    ○ 乱数種の設定
    ○ 引数にseedプロパティを持ったオブジェクトを渡す
    ● .random() で乱数生成を行う
    ● .seed で複製ができる
    ● サブPRNGの作成:randomSeed()
    No56: 30s
    https://github.com/tc39/proposal-seeded-random

    View Slide

  59. WeakRefs (@likr)
    ● Stage 4 (2020年7月)、ES2021
    ● GCに回収されても良いような弱参照を実現
    ○ キャッシュ機構の実装
    ○ destructor(WebAssembly向け)
    ● WeakRef class
    ● FinalizationRegistry class
    変数、配列、
    オブジェクト
    弱参照
    変数、配列、
    オブジェクト
    オブジェクト オブジェクト
    GC対象外
    弱参照
    オブジェクト オブジェクト
    GC対象
    No1: 90s
    DEMO

    View Slide

  60. sosukesuzuki import.meta
    - 数少ない Meta Property の1つ
    - 現在実行中のモジュールにホスト固有のメタデータを提供する
    - ECMAScript ではオブジェクトであることしか決まっていなくて、中身はホスト環境
    に委ねられている
    - Web では import.meta.url が生えている
    - 実行されているモジュールの URL を表す
    - https://sosukesuzuki.dev/index.mjs では import.meta.url は https://sosukesuzuki.dev/index.mjs
    - Node.js でも import.meta.url のみ生えている
    - 実行されているモジュールのファイルの URL を返す(file スキームになる)
    - ESM では __filename や __dirname を使えないので、その代わりになる
    - “module” モジュールの createRequire の引数の import.meta.url を渡すと CJS Modules での
    require が手に入る
    - 移行や相互運用の際に便利
    No2: 60s
    DEMO

    View Slide

  61. Promise.any() @okunokentaro 60s
    ● ES2021で追加
    ● Promise.all()とかの仲間
    Support すべて待つか rejectが含まれたら
    Promise.all() ES2015 待つ すべて待たずにrejectを返す
    Promise.race() ES2015 待たずに最初のresolve/rejectを返す そのrejectを返す
    Promise.allSettled() ES2020 待つ すべて待ってすべての結果を返す
    Promise.any() ES2021 待たずに最初のresolveを返す すべてがrejectのときAggregateError
    https://github.com/tc39/proposal-promise-any
    https://stackblitz.com/edit/rxjs-bhelsu
    No3: 60s
    DEMO

    View Slide

  62. import() ES2020
    ● ESMを動的にimport (dynamic
    import)
    ● 引数にmoduleのpath渡す
    ● 非同期関数で、結果を resolve
    するPromiseを返す
    ● named exportはnameがkey
    ● default exportは”default”が
    key
    @arayaryoma
    No4: 30s
    DEMO

    View Slide