Block Params

A syntactical simplification in JS to enable DSLs

About me

わだまる / tsuyoshiwada

Web Developer (CyberAgent CATS).
GitHub: tsuyoshiwada, Twitter: @wadackel

Block Params とは ?

Kotlin、Ruby、Groovy をインスパイアした構文の簡略化を実現する仕様です。
(最近だと SwiftUI で注目を浴びたように思います)

複数のパラメータをとる関数である場合

関数呼び出しで最後のパラメータが関数の場合、括弧を省略しブロックのみを渡すことができます。

fn(1) {
  // ...
}

👇

fn(1, () => {
  // ...
});

パラメータが単一の関数である場合

呼び出す対象が単一の関数のみを受け取るシグネチャである場合、括弧を丸ごと省略することができる。

a {
  // ...
}

👇

a(() => {
  // ...
});

ネスト

Block Params のネストを有効にしたいが、現在まだ検討段階とのこと。

親のブロックを参照する例

a(1) {
  ::b(2) {
    // ...
  }
}

👇

a(1, __parent__ => {
  __parent__.b(2, __parent__ => {
    // ...
  });
});

ブロックへと引数を渡す例

a(1) do (foo) {
  // ...
}

👇

a(1, foo => {
  // ...
});

ユースケース

実際に使用した際のイメージを掴みやすくするサンプルコードを幾つか抜粋。

Swift's defer

defer (100) {
  // internally calls setTimeout(100)
  alert("hello world");
}

Error Handling — The Swift Programming Language (Swift 5.1)

C#'s foreach

// works on arrays, maps and streams
foreach (array) do (item) {
  console.log(item);
}

C# foreach statement | Microsoft Docs

kotlin's templates

let body = html {
  ::head {
    ::title("Hello World!") {}
  }
  ::body {
    ::div {
      ::span("Welcome to my Blog!") {}
    }
    for (page of ["contact", "guestbook"]) {
      ::a({href: `${page}.html`}) { span(`${page}`) } {}
    }
  }
}

Type-Safe Builders - Kotlin Programming Language

完了値の扱い

Block Params が値を返す場合、
呼び出し元の関数へと値を返すことが望ましい (Like Kotlin) が、
どのようになるのかはまだ検討中。

let result = foreach (numbers) do (number) {
  number * 2 // gets returned to foreach
}

do expressionsstatement-like expressions のセマンティクスを借りたものが
現実的な落とし所になりそう 🤔

その他の検討事項

既存の言語仕様との兼ね合いや、
理想状態と実現方法の落とし所が見つかっていない部分を
模索をしているように見えます。

  • Scoping
  • Bindings
  • return
  • continue
  • break

もっとたくさんのサンプルコードが見たい

test ディレクトリの中にあるコードが読んでいていて楽しいです。

所感

  • 遊び心のある構文で個人的には好き
  • 簡略化された構文の上に、ユースケースによっては実用性 (可読性含む) が感じられる
  • 2017/08/04 に初めてまともなコミットがあってからも、まだまだ検討事項は多く見える

Related Proposal & Discussion

Thank you 🐶 !