Build Insiderオピニオン:河合宜文(4)
各言語に広まったRx(Reactive Extensions、ReactiveX)の現状・これから
―― RxやRoslynに見るMicrosoftのオープンソース戦略の変化 ――
.NETから始まったRx(Reactive Extensions)が、なぜRxJavaやRxJSなど他の開発言語で人気を集めているのか。“ReactiveX”とは何か? そしてRxは、これからどう進化していくのか。
Rxの登場とその広まり
2009年にマイクロソフトが初めて.NET Frameworkに向けて提供を開始したReactive Extensions(Rx)ライブラリ「Rx.NET」は、今ではさまざまな開発言語に移植され、幅広く使われている。Java/Android用のRxJava(GitHub Star 13506)、JavaScript用のRxJS(GitHub Star 9432)、Swift用のRxSwift(GitHub Star 4472)などは、その代表ともいえるもので、利用事例数においても、情報量においても、もはやRx.NETを引き離しているといっても過言ではないだろう。
なぜRxがここまで広まることができたのか。それはRxの本質的な部分が、言語の枠を超えられるほど、限りなく「シンプル」だったからだと考えている。その本質はシンプルなインターフェース、つまりIObservable<T>
インターフェースとIObserver<T>
インターフェースの「発見」にある。これらはC#で記述すると、リスト1のようになる。
public interface IObservable<T>
{
IDisposable Subscribe(IObserver<T> observer);
}
public interface IObserver<T>
{
void OnCompleted();
void OnError(Exception error);
void OnNext(T value);
}
|
どの言語に持っていっても変わりようのない、研ぎ澄まされた形。そこに使い心地の良いメソッドチェーンやコレクション操作演算子のフレーバーをかぶせれば、Rxのように見えるものができてくる。
さて、それほどのポテンシャルがRxにあったのではあるが、その普及に一役買ったのはマイクロソフトではなく、ネットフリックス(Netflix)だろう。RxJavaはネットフリックスにより開発され2013年に公開された。以降、ネットフリックス自身が講演で実例を示したり、ドキュメントを整備したり、さまざまな言語に移植されたReactive Extensionsを束ねるReactiveXをリードしたりするなどして、強く普及に努めている。
ではなぜネットフリックスがマイクロソフト発祥のテクノロジを利用するようになったのだろうか。実は、RxJavaの初期の開発者であるJafar Husain氏は、もともとマイクロソフトに勤めていて、世界で最初にReactive Extensionsを紹介した人物でもあるのだ。その後にネットフリックスに転職し、RxJavaの誕生に深く関わることになる。
一方でオリジナルのRx.NETの作者であるErik Meijer氏もまた、マイクロソフトを辞めた後に、HackやDartなどの新興言語の支援に関わる他、Principles of Reactive Programmingといった学習コースをScalaの作者であるMartin Odersky氏らと開講するなど、言語の枠を超えて活躍している。
Rxとマイクロソフトのオープンソース
昨今のマイクロソフトのオープンソースへの傾倒を疑うものはもはやいないだろう。少し例を挙げるだけでも、TypeScript、C#コンパイラー(“Roslyn”)、ASP.NET、.NET Coreなどがオープンソースプロジェクトとして開発されている。その中でもRx.NETは2012年と比較的早期にオープンソース化された(当時はCodePlexでホストされ、現在はGitHubに移行している)。
Rx.NETに対して当時(今も、かもしれないが)強く望まれていたのは.NET Frameworkに仲間入りすることであったが、これは今も達成されていない。しかし、Immutable Collectionsのような重要な新コレクションライブラリでさえもNuGetで提供されていること、.NET CoreはNuGetを介して小規模なアセンブリパッケージをリリースするモジュール形式になっていることなどを考えると、今となっては「Rx.NETは.NETの行く先を示していた」と肯定的に捉えられるかもしれない。
OSS(オープンソース・ソフトウェア)ライブラリとしてのRx.NETは成功したのだろうか。公開には十分な意義とインパクトがあったが(当時のMonoで利用しやすくなったことは最大の功績だろう)、成功したOSSライブラリによく見られる「活発なディスカッションと貢献によってスピード感を持って進化していく姿」が見られることはなかった。
Rx.NETのStable版のリリースは2014年7月23日で止まっている。これはRx.NETが十分に成熟したライブラリであるからと見なすことも可能ではある。しかしその一方で、RxJavaに目を向けると、Backpressure(=処理可能なデータ量を送信側に通知することで自律的に流量を調整する仕組み)のサポートやSingle
クラス(長さが1のIObservable<T>
インターフェースに近いもの)、Completable
クラス(長さが1のIObservable<Unit>
インターフェースに近いがOnNext
メソッドがないObserverしか受け取らないもの)など、少しRxを使い込んでいくと欲しくなるものについてしっかりとした議論がなされ、APIが練られた上でリリースされている。こうしたことが各言語用のライブラリを取り巻く熱量の差をあらわにしているように思える。
マイクロソフト発のOSSライブラリの全てがそうだというわけでは決してない。例えば、Roslynはマイクロソフトが強くイニシアティブを持ちながらも、多くの議論を交わしながら活発に動いている。また、多数のContributorと共に開発が進んでいる“Orleans”もある。Rx.NETは、どちらかというと、その少し前の世代のマイクロソフトのOSSライブラリであるpatterns & practices Enterprise Libraryのような重たさ、あるいはコミュニティとの関わりとのぎこちなさを引きずっているのかもしれない。
patterns & practicesからは、MVVMライブラリのPrismがマイクロソフトの手を離れコミュニティに引き渡された。マイクロソフトの手を離れる。この動きは、コメント欄の最初に「So this means prism is dead yes?」と書かれているように、一昔前では死を意味したかもしれない。しかし、Prismはむしろ再生を果たしている。コミュニティに引き渡されたことで、止まっていた時間が再び動き出し、新しい進化を遂げようとしている。時代はマイクロソフト純正であることの保証よりも、止まらない成長をこそ求めているのだ。
Rxのこれから
Rx.NETも決して止まっているわけではない。BingやCortanaの内部ではより進化したRxが使われている。その一端が2014年の11月に発表された講演「Cloud-Scale Event Processing Using Rx(英語)」で示された。その中ではIReactiveProcessing
モデルによるReactiveなクラウドコンピューティングが説明されただけでなく、Rx v3.0の計画も発表され、そこには非常に野心的な言葉が並んでいた。しかし残念ながら今はもう2016年。果たして、これらの構想が今後どのような形で登場することになるのだろうか……。
他言語では「Rxに影響を受けたもの」から「Rxそのもの」へと集約が進み始めているように見える。例えばBacon.js(Rxに影響を受けたもの)とRxJS(Rxそのもの)。ReactiveCocoa(Rxに影響を受けたもの)とRxSwift(Rxそのもの)。「Rxに影響を受けたもの」はそれぞれRxの影響を強く受けながらも、「Rxの欠点と思える点(特にHotとColdの辺りについて強く言及される)を直した」としている。それでもなお、これらがRxへと集約されていっているのは、Rxが共通言語としての強さを持つようになってきたからかもしれない。当初、Rxが各言語に受容され普及が始まったときには、その本質的な部分、つまり「インターフェースとコレクション操作に見立てた概念」に重きが置かれていたが、今は「共通言語としてのRx」にも強い価値が生まれてきたということに思える。
RxJSのv5(ベータ版。※現在はv4)では、そのリポジトリが(マイクロソフトのReactive-Extensions/RxJSから)ReactiveX配下のReactiveX/rxjsへと移り、開発もマイクロソフトから、主にネットフリックスの@bleshやCycle.jsで有名な@staltzらへと移っている。TypeScriptで書かれ、ES6を意識し、よりJavaScriptらしくなり、またコードがRxJavaベースとなったことでパフォーマンスもよりよく(RxJS v4はRx.NETの1.0ベースのコードで、Rx.NET 2.0のものとも違う、少し古くあまりパフォーマンスのよくない形)、デバッガビリティもより高いものになっているようだ。
■
最後に、筆者自身が開発しているゲームエンジンUnity用“ReactiveX”の「UniRx」についても簡単に紹介したい。基本的に私が1人で開発をしている形であるが、アクティブに開発を続けていて、より性能高く、よりUnityにフィットした形を目指して更新を続けている。GitHubのStar数が現在753と各言語用“ReactiveX”の中で比較しても遜色のない人気を獲得している。また、採用例も非常に増えてきているので、実績としても申し分ないだろう。Unityユーザーはぜひ試してみてほしい。
言語や環境を超えて、進化を続けているRx。本稿で示したように、今やあらゆるエンジニアの共通言語・共通技術となりつつあるので、「まだ使っていない」という人はぜひこの記事をきっかけにして、今からRxの世界を体験することをお勧めする。私自身もUniRxの開発を通して、Rxの実証にこれからも貢献していきたい。
河合 宜文 (かわい よしふみ)
株式会社グラニ取締役CTO。Microsoft MVP for Visual C#。特にLINQが非常に好き。最近はUnity開発においてもLINQをフル活用するために、Unity用のReactive Extensions「UniRx」を作っています。
・ブログ: http://neue.cc/
・Twitter:@neuecc
1. 最先端のC#環境で働く開発者が感じたVisual Studio 2015移行への期待
最先端のC#環境でゲーム開発を行っているグラニでは、Visual Studio 2015 Previewを見て何を感じたのか。LINQとReactive Programmingで有名なneuecc氏によるコラム、始動。
2. Visual Studio 2015を前のめりに使いこなす! Analyzerの社内導入と展開
「using CSharp;」な企業であるグラニでは、Roslynが提供する「Analyzer」と呼ばれるコードの解析/生成機能をどう活用しているのか。その秘訣をチラリとご紹介。
3. C#における構造化ログの手法、そしてデータ可視化のためのDomoの薦め
最近、より重要性を増しているログ。グラニではログをどのような方法で扱っているのか、そして、その根底にあるグラニのポリシーとはどんなものだろう。