Posted at
CureAppDay 16

どうなるbind operator proposal

More than 1 year has passed since last update.


bind operator proposalとは?

ECMAScriptへの新しい文法の提案の1つ。



  • obj::func()と書けばfunc.call(obj)になる


  • ::obj.method と書けば obj.method.bind(obj)になる

という新しい文法を提案している。

babelですでに実装されており、熱烈なサポーターもいるが、

TC39 stageは未だに0。 (TC39のstageについてはazuさんのECMAScriptとは何か?に詳しい)

もう一方の期待の新星 async/await が着々とstageを上げているなか、何故bind operator proposalは一向に進まないのか。

本記事は主に、その理由として挙げられている下記のgithub issuesの流れをまとめたものである。


bind operator proposalが進まない理由

紐解いていくと、2つの課題があった。


  1. TC39のメンバーで推進役がいない

  2. 2つの別な機能が別々な問題を抱えている


推進役 = champion の不在

各提案にはchampionと呼ばれる、TC39のmemberで、この提案を推し進める代表的存在が必要なのだという。

この提案にもchampionはいたが、彼はすでにTC39のmemberとしては働いていなかった。

今年7月に、別なmemberが「私がchampionになります」という発言をして盛り上がりを見せたが、それっきり出番がないような状況だ。


2つの別な機能を1つで提案している

実はこの提案は、2つの別な機能の提案になっている。



  1. obj::func()と書けばfunc.call(obj)になる機能


  2. ::obj.method と書けば obj.method.bind(obj)になる機能

issue内では、1をinfix notationと表現し、2をprefix notationと表現していたが、それぞれが別な課題を抱えていた。


infix notationの動的thisの変更は混乱を招く

infix notationは、thisを、敢えて、動的に変える、という操作だ。

これは混乱のもとになるのではないか。

ES2015では、古来からJSに存在した「thisが変わるってどういうこと?」問題に取り組み、thisを束縛する関数定義の文法を作ったのだが、

このinfix notationは、その方針に逆行しまいか、ということである。


prefix notationは見た目がよくない

prefix notationが解決するのは、

arr.forEach(...args => console.log(...args))

を、

arr.forEach(::console.log)

にすることだ。(実際にはconsole.logはthisがなくても動作するようになってきているようだが)

Reactなどで下位のコンポーネントにthisを束縛した状態でメソッドを渡したい場合にも有効だ。

しかし、他のプログラミング言語で、::から始まる構文がない(あったらコメントよろしく)ため、

見た目がよくなく感じるのだろう。


別で提案するのがよいのか

infix notationとprefix notationは、待ちわびている層が違う印象がある。

RxJS勢はinfix notationを待ちわびている

underscoreやlodashのようなutility系も、この文法が取り入れられたら、thisをベースにするものに置き換えられていくだろう。

一方prefix notationは、「あったら便利だよね」「v8はbindに比べて最適化できる余地がありそう」といった程度で、そこまで急ぐ理由も見えない、という印象がある。

ただ多くのイベント駆動型ライブラリ、もちろんReactでも、小さな幸せを手に入れることができる。

個人的にはredux sagaのSVO記法(主語、動詞、目的語の順に引数に入れて関数呼び出しを宣言的に書くもの)などが今後増えるときに、より便利になるのではないかと思う。

このように、解決したい課題も違うし、抱えている問題も違うので、分けてしまえばいいのではという意見があった。

しかし、分けたら分けたで、2人のchampionが必要になり、自体は混迷を極めている...。


ファンとして

infix operatorは劇薬的だ。魅力的だが、乱暴な使い方が怖い。

1人で楽しむ分には最高だが、チームだと「このthisはどこに使われる想定なん?」となる。

だから、filtermapなど、汎用の処理群でのみ使われる世界になるように、

利用側が行儀よくしている必要がありそうだ。

prefix operatorは、最適化のカギになってくれという期待がある。

例えばReactで、

<SomeComponent onClick={::this.sendSomething} />

これがしたいが、これは(軽微だが)パフォーマンス問題がある。

コンストラクタで一度だけbindするのが筋だということだ。

でも、「bind関数じゃなくて文法なので、最適化でパフォーマンス問題を解決してくれる」的な

未来を期待している。

来年からは、ファンはやきもきしているだけでなく、もっと態度で示していけるよう、

コミュニティを盛り上げられればと思う。