Block Params
A syntactical simplification in JS to enable DSLs
- Stage: 1
- Repository: samuelgoto/proposal-block-params
- Date: 2019/10/09
- #tc39_study: TC39 Proposals LT 大会
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");
}
C#'s foreach
// works on arrays, maps and streams
foreach (array) do (item) {
console.log(item);
}
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}`) } {}
}
}
}
完了値の扱い
Block Params が値を返す場合、
呼び出し元の関数へと値を返すことが望ましい (Like Kotlin) が、
どのようになるのかはまだ検討中。
let result = foreach (numbers) do (number) {
number * 2 // gets returned to foreach
}
do expressions や statement-like expressions のセマンティクスを借りたものが
現実的な落とし所になりそう 🤔
その他の検討事項
既存の言語仕様との兼ね合いや、
理想状態と実現方法の落とし所が見つかっていない部分を
模索をしているように見えます。
- Scoping
- Bindings
return
continue
break
もっとたくさんのサンプルコードが見たい
test ディレクトリの中にあるコードが読んでいていて楽しいです。
所感
- 遊び心のある構文で個人的には好き
- 簡略化された構文の上に、ユースケースによっては実用性 (可読性含む) が感じられる
- 2017/08/04 に初めてまともなコミットがあってからも、まだまだ検討事項は多く見える