読者です 読者をやめる 読者になる 読者になる

RxJSをもくもくしてReactivePropertyの価値らしきものを気づかされた話(仮)

javascript ECMAScript ReactiveX

Reactive Extensions JS port(RxJS)をもくもくしていた結果、C#界隈がReactive Propertyを作り出した理由が(なんとなく)わかってきた。

Rxの流儀にのっとれば、ある値を使おうとする場合、その値を生成するObservableの結果を受けて、そのObservableも同様に……とObservableの依存関係を作っていく必要がある。

Rx.Observable.do()メソッド中に、関数外のグローバル変数などを副作用なmutateをさせてもいいが、これは基本的によろしくない。Rxで実行される各Observerが、一体どのタイミングが動作するかの順序保証が本来的には存在しないためだ。イベントループがひとつしかない & Workerは完全にメモリ空間が分割されたアクターライク & Rx.SchedulerもDOMのイベントループ原則に則るJavaScript portではそこまで極端な問題にはならないかもしれないが、その他多くのメモリ空間共有型のスレッドを用いる種類の言語では容易にdata raceなどの問題を抱えることとなるように感ずる。

この問題を避けるには依存関係にある値のObservableを愚直に紡いでいけば良いのだが、従来の手続き型プログラミングに慣れた我々には慣れない面があるし、明らかに冗長とも思えるケースがある。突如として飛び道具的に副作用を起こして問題を解決したい場合もある。行儀がいいとは言えないが、GUIプログラミングではこういう需要はままある気がするし、そもそも言語が副作用の存在を許容している以上、その帳尻を合わせる為にどこかで泥を被る必要がある。

こうした問題に対してC#の人々が考えついたアプローチがReactivePropertyであるということに気づいた(名前だけは知っていた)。値そのものをRx.Observableに変換できるコンテナを用意し、可逆的な変換も可能なコンテナ。値の変更が起これば、そのイベントをObserverへと伝播させる。

値のmutateは副作用であるが、Observableのチェーンをつなぐことで依存関係を表明することができる。サンプルコードを見るだけでは結構危なっかしいし、GCあり言語だなと感じる面もある。が、値のmutationに伴って、イベントが常に流れ続け、それが最終的にatomicに値を上書きするのだと気付くと、妥当感にあふれる。いい意味で言語的クリーンさを無視している。良い。

さっそくRxJSでも使ってみようと思ったが、同名かつNode.jsのEventEmmitterを使ったライブラリは何点か見つかるが、Rxベースのものはない。これはライブラリ作成のチャンスかもね(本業でRxを実戦投入するには必要と思われるので、その時は自分でなんとかするかもしれない)。

しかしこうして見ると、言語に後付けて導入したモデルとしては、Reactive Extensionsは本当に良い塩梅で出来ている。もちろん私が地雷を踏んでいない可能性もある。API designがVisual StudioのIntellisenseによる補完が明らかに前提となっていて、IDEの支援無しに書くには二の足を踏むのは否定できない(Visual Studio + TypeScriptで解決するとは思うけど)。ただ、これを見た後にES7 Object.observeをみると、Promiseなど以前のパラダイムに生きているなんとも中途半端感を感じずにはいられない。

「オメー何言ってるんだ、それは違う」というC#系の方がいらっしゃいましたらツッコミをお願いします