現在の機能的リアクティブプログラミング実装のステータスは何ですか?


90

Haskellでいくつかの単純な自動物理システム(振り子、ロボットアームなど)を視覚化しようとしています。多くの場合、これらのシステムは次のような方程式で記述できます。

df/dt = c*f(t) + u(t)

ここでu(t)、ある種の「インテリジェントコントロール」を表します。これらのシステムは、関数型リアクティブプログラミングパラダイムに非常にうまく適合しているように見えます。

そこで、Paul Hudak氏の著書「The Haskell School of Expression」を手に取ってみたところ、そこに提示されているドメイン固有言語「FAL」(Functional Animation Language)は、私の単純なおもちゃシステムでは非常にうまく機能していることがわかりましたintegrate。効率的に使用するには少し面倒すぎるようですが、簡単に修正できます)。

私の質問は、今日のより高度な、または実用的なアプリケーションのための、より成熟した、最新の、よく維持された、パフォーマンス調整された代替手段は何ですか?

このWikiページにはHaskellのいくつかのオプションがリストされていますが、以下の点については明確ではありません。

  1. (私が理解しているように)このプログラミングパラダイムの発明者の1人であるConal Eliottのプロジェクト「reactive」のステータスは、少し古く見えます。私は彼のコードが好きですが、多分私は他のより最新の代替案を試すべきですか?構文/パフォーマンス/実行時の安定性の点で、それらの主な違いは何ですか?

  2. 2011年の調査のセクション6 から引用すると、「... FRPの実装は、レイテンシの保証が必要なドメインで効果的に使用するには、まだ十分に効率的または予測可能ではありません...」。FRPが15年以上存在しているという事実を考えると、調査はいくつかの興味深い可能な最適化を示唆していますが、このパフォーマンスの問題は少なくとも数年以内に解決するのが非常に、または本質的に難しい場合があるという印象を受けます。これは本当ですか?

  3. 調査の同じ著者は彼のブログで「時間の漏れ」について語っています。問題はFRPに固有のものですか、それとも純粋で厳密でない言語でプログラミングするときに一般的に発生する問題ですか?FRPベースのシステムを長期間にわたって安定させることは、十分に高性能ではないにしても、非常に難しいと思ったことはありませんか?

  4. これはまだ研究レベルのプロジェクトですか?プラントエンジニア、ロボット工学エンジニア、金融エンジニアなどの人々が実際にそれらを使用していますか(ニーズに合った言語で)?

私は個人的にはHaskellの実装を好んでいますが、他の提案も受け入れています。たとえば、Erlangを実装するのは特に楽しいでしょう-インテリジェントで適応性のある、自己学習型のサーバープロセスを用意するのは非常に簡単です。

回答:


82

現在、関数型リアクティブプログラミング用の実用的なHaskellライブラリが主に2つあります。どちらも一人で管理していますが、他のHaskellプログラマーからのコード提供も受けています。

  • Netwireは、効率、柔軟性、および予測可能性に重点を置いています。独自のイベントパラダイムがあり、ネットワークサービスや複雑なシミュレーションなど、従来のFRPが機能しない領域で使用できます。スタイル:適用可能または矢印付き。最初の作者とメンテナー:ErtugrulSöylemez(これは私です)。

  • 反応性バナナは、従来のFRPパラダイムに基づいています。使用することは実際的ですが、古典的なFRP研究の基礎としても役立ちます。その主な焦点はユーザーインターフェイスにあり、wxには既製のインターフェイスがあります。スタイル:適用。最初の作者およびメンテナー:Heinrich Apfelmus。

両方を試す必要がありますが、アプリケーションによっては、どちらかがより適していることがわかります。

ゲーム、ネットワーキング、ロボット制御、シミュレーションには、Netwireが役立ちます。透過的なイベント処理のためのさまざまな有用な差動、積分、および多くの機能を含む、これらのアプリケーション用の既製のワイヤーが付属しています。チュートリアルについては、Control.Wireリンクしたページのモジュールのドキュメントにアクセスしてください。

グラフィカルユーザーインターフェイスの場合、現在のところ、最適な選択はリアクティブバナナです。すでにwxインターフェースが(別のライブラリreact-banana-wxとして)あり、Heinrichはコードサンプルを含むこのコンテキストでFRPについて多くのブログを書いています。

他の質問に答えるには:FRPは、リアルタイムの予測可能性が必要なシナリオには適していません。これは主にHaskellによるものですが、残念ながらFRPは低レベル言語で実現するのが困難です。Haskell自体がリアルタイム対応になるとすぐに、FRPもそこに到達します。概念的には、Netwireはリアルタイムアプリケーションに対応しています。

時間のリークはモナドフレームワークに大きく関係しているため、もはや問題にはなりません。実際のFRP実装は、モナディックインターフェイスを提供しません。Yampaがこれを開始し、Netwireとリアクティブバナナの両方がその上に構築されています。

現在、FRPを使用する商用プロジェクトやその他の大規模プロジェクトについては知りません。ライブラリは準備ができていますが、人々はまだ準備ができていないと思います。


すばらしい回答です。ありがとうございます。ライブラリの上に強化学習アルゴリズムを実装するのは楽しい練習になります。
2012年

3
特に、Haskell(Nikki and the Robots)で書かれた最近のインディーゲームでは、FRPを使用しないことにしました。
Alex R

23

すでにいくつかの良い答えがありますが、私はあなたの特定の質問に答えようとするつもりです。

  1. 時間リークの問題により、reactiveは深刻なプロジェクトには使用できません。(#3を参照)。最も類似したデザインの現在のライブラリーは、反応性をヒントにして開発された、反応性バナナであり、Conal Elliottとの議論においてです。

  2. Haskell自体はハードリアルタイムアプリケーションには不適切ですが、場合によっては、Haskellをソフトリアルタイムアプリケーションに使用することもできます。私は現在の研究に精通していませんが、これが克服できない問題であるとは思いません。Yampaのようなシステム、またはAtomのようなコード生成システムのいずれかが、おそらくこれを解決するための最良のアプローチであると私は思います。

  3. 「時間リーク」は、切り替え可能なFRPに固有の問題です。このリークは、将来のある時点で切り替えが発生した場合に古いオブジェクトが必要になる可能性があるため、システムが古いオブジェクトを解放できないときに発生します。メモリリーク(かなり深刻になる可能性があります)に加えて、切り替えが発生すると、古いオブジェクトのチェーンがトラバースされて現在の状態が生成される間、システムが一時停止する必要があります。

Yampaや古いバージョンの反応性バナナなどの切り替え不可能なfrpライブラリは、時間のリークの影響を受けません。切り替え可能なfrpライブラリは、一般に、FRP値が作成される特別な「作成モナド」を使用するか、「エージング」タイプのパラメーターを使用して切り替えが発生するコンテキストを制限する、2つのスキームのいずれかを使用します。 elerea(およびおそらくnetwire?)は前者を使用しますが、最近の反応性バナナとグレープフルーツは後者を使用します。

「切り替え可能なfrp」とは、Conalの機能switcher :: Behavior a -> Event (Behavior a) -> Behavior aまたは同一のセマンティクスを実装するものを意味します。これは、実行中にネットワークの形状が動的に切り替わることを意味します。

これは、モナディックインターフェイスに関する@ertesのステートメントと実際には矛盾しません。Monadインスタンスの提供Eventにより、時間のリークが発生する可能性があり、上記のいずれのアプローチでも、同等のモナドインスタンスを定義できなくなったことがわかります。

最後に、FRPで実行する作業はまだたくさん残っていますが、新しいプラットフォームのいくつか(reactive-banana、elerea、netwire)は安定しており、十分に成熟していて、それらから信頼できるコードを構築できます。ただし、優れたパフォーマンスを得る方法を理解するには、多くの時間を費やす必要があるかもしれません。


2
矢印ベースのライブラリ(Yampa、netwire)についても、切り替え可能です。その理由は、矢には老化が組み込まれているため、実際にはそれを取り除くことができないからです。(矢印はストリームトランスフォーマーであるため、入力ストリームの開始時間にとらわれません。)
Heinrich Apfelmus


1
@HeinrichApfelmus:それは興味深い点です。私は一般に、矢印ベースのライブラリを、elerea / grapefruit / current-reactive-bananaと同じように切り替え可能だとは考えていません。彼らの切り替えは、リアクティブバナナの以前のバージョンで必要だったものに非常に近いと思います。ただ、これは直感ですが、私が言っていることを説明するのに十分な考察をしていません。
John L

2
@DanBurtonのおかげで、その名前を思い出そうとして失敗しました。ナトリウムは反応性バナナほど一般的ではありませんが、現代のFRPライブラリと見なす必要があることに同意します。
John L

進行中の議論は少し難しいですが、GC時間に何らかの制限がある場合は、ソフトリアルタイムシステムが実際に可能であることを示しているようです。とにかく素晴らしい答えをありがとう。
mnish

20

Monoと.Netのスペースにいくつかのアイテムをリストし、あまり前に見つけなかったHaskellスペースのアイテムをリストします。Haskellから始めます。

Elm- リンク

サイトごとの説明:

Elmは、フロントエンドWeb開発をより快適にすることを目的としています。HTML、CSS、JavaScriptの体系的な問題を修正するGUIプログラミングへの新しいアプローチを紹介します。Elmを使用すると、ビジュアルレイアウトをすばやく簡単に操作したり、キャンバスを使用したり、複雑なユーザー入力を管理したり、コールバック地獄から脱出したりできます。

FRPには独自のバリアントがあります。その例で遊んでみると、かなり成熟しているようです。

リアクティブ拡張- リンク

フロントページからの説明:

Reactive Extensions(Rx)は、監視可能なシーケンスとLINQスタイルのクエリ演算子を使用して、非同期でイベントベースのプログラムを作成するためのライブラリです。開発者はRxを使用して、Observableで非同期データストリームを表現し、LINQ演算子を使用して非同期データストリームをクエリし、スケジューラを使用して非同期データストリームの同時実行性をパラメーター化します。簡単に言えば、Rx = Observables + LINQ + Schedulersです。

Reactive ExtensionsはMSFTから提供され、イベントの処理を簡素化する多くの優れた演算子を実装しています。ほんの数日前にオープンソース化されました。非常に成熟しており、本番環境で使用されています。私の意見では、TPLライブラリが提供するよりも、Windows 8 APIのAPIが優れていたでしょう。なぜなら、オブザーバブルは高温と低温の両方であり、再試行/マージなどが可能ですが、タスクは常に、実行中、障害、または完了した高温または完了した計算を表します。

非同期性のためにRxを使用してサーバー側のコードを記述しましたが、C#で機能的に記述するのは少し面倒なことを認めなければなりません。F#にはいくつかのラッパーがありますが、グループが比較的閉鎖されており、他のプロジェクトのようにMSFTによって昇格されないため、API開発を追跡するのは困難です。

そのオープンソースは、IL-to-JSコンパイラのオープンソースに付属しているため、おそらくJavaScriptまたはElmでうまく機能します。

RabbitMQやSocksJSなどのメッセージブローカーを使用して、F#/ C#/ JS / Haskellを非常に適切にバインドすることができます。

Bling UIツールキット- リンク

フロントページからの説明:

Blingは、MicrosoftのWPF / .NETで画像、アニメーション、相互作用、視覚化を簡単にプログラミングできるC#ベースのライブラリです。Blingは、豊富なUIデザインアイデアの迅速なプロトタイピングを支援するために、設計技術者、つまりプログラミングを行うデザイナーを対象としています。学生、アーティスト、研究者、愛好家も、アイディアや視覚化をすばやく表現するためのツールとしてブリンが役立つことを実感します。BlingのAPIと構造は、プロダクションコードの注意深いプログラミングとは対照的に、使い捨てコードの高速プログラミング用に最適化されています。

無料のLtU記事

私はこれをテストしましたが、クライアントプロジェクトでは動作しませんでした。見栄えがよく、値間のバインディングを形成するC#演算子のオーバーロードが優れています。WPF / SL /(WinRT)の依存関係プロパティをイベントソースとして使用します。その3Dアニメーションは、適切なハードウェアでうまく機能します。視覚化が必要なプロジェクトになってしまう場合は、これを使用します。おそらくそれをWindows 8に移植します。

ReactiveUI- リンク

以前はMSFTにいて、現在はGithubにいるPaul Bettsがそのフレームワークを作成しました。私はそれをかなり広範囲に使って、モデルが好きです。Blinkよりも分離されている(その性質上、Rxとその抽象化を使用しているため)-これを使用してコードを単体テストするのが簡単になります。Windows用のgithub gitクライアントはこれで書かれています。

コメント

リアクティブモデルは、ほとんどのパフォーマンスが要求されるアプリケーションに対して十分なパフォーマンスを発揮します。ハードリアルタイムについて考えている場合は、ほとんどのGC言語で問題が発生していると思います。Rx、ReactiveUIは、GCする必要がある小さなオブジェクトをいくらか作成します。これは、サブスクリプションが作成/破棄され、中間値がコールバックのリアクティブ「モナド」で進行するためです。一般に.Netでは、タスクベースのプログラミングよりもリアクティブプログラミングを好みます。なぜなら、コールバックは静的(コンパイル時に既知で、割り当てはありません)で、タスクは動的に割り当てられます(不明、すべての呼び出しにはインスタンスが必要で、ガベージが作成されます)。ラムダはコンパイルされます。コンパイラが生成したクラス。

明らかにC#とF#は厳密に評価されるため、ここではタイムリークは問題になりません。JSについても同様です。ただし、再生可能またはキャッシュされたオブザーバブルでは問題になる可能性があります。


すばらしい答えをありがとう。Haskell FRP実装で気に入った点の1つは、コントロールの計算u(t)とのシミュレーションを完全に分離できるように見えることですf(t)。F#実装の場合はそうですか?
2012年

確かに、これら2つの機能は一時的に分離されていると言えるでしょう。それらはおそらく論理的に分離されていません。;)
Henrik

私の知る限り、Reactive Extensionsと他のより洗練されたUI(フォーカスされたパッケージ(実際にはHaskellの外にあるすべてのもの)はイベントセマンティクスのみを使用します)、つまり、スイッチをオンにできるイベントの概念があるということです。しかし、等式に相互作用できる連続時間信号の概念ではありません。guiを作成する場合、これで問題ないと思います。ただし、シミュレーションとモデルを構築する場合、これは残念なことです。
sclv

すべての関数型反応型プログラミングライブラリの実装が時間を離散的にではなく継続的にモデル化する必要があることを意味していますか?「Process Algebra with Timing:Real Time and Discrete Time」という論文を見つけました。これは、あなたが何について話しているのかを理解するための良い出発点ですか?
Henrik

私はすべてが必要だと言っているわけではありません-必要なものもそうでないものもあります。しかし、実行するものは特定のタスクにより適し、そうでないものは他のタスクには適していません...
sclv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.