- タイトル: リアクティブプログラミングにおける時変値永続化の試み
- 講演形式: MS Teams
- 日時: 2021年2月24日 (水) 15:00-16:40
- 講演者: 大分大学 理工学部 准教授 紙名哲生 先生
- connpass
- スライド
概要(コピペ)
リアクティブプログラミング(RP)言語では、時間変化する値(時変値、シグナルともいう)の間の関係を宣言的に記述しておけば、あるシグナルの値変化はその関係を辿って他のシグナルへと自動的に伝播される。
また、値変化を出力などの副作用に伝播させる場合もある。これらの機能は、GUIやセンサとモータの連携など、時間変化する入力列を処理するプログラムの記述に便利である。
Javaを拡張したRP言語SignalJでは、文法拡張のほとんどないシンプルなプログラミングインタフェースでこれらの機能を扱うことができる。
本講演では、RP言語やSignalJの機能をひと通り紹介した後、任意の過去に遡ってシグナル値を取得できる永続シグナルの実現方法について議論する。永続シグナルによる分散RPの実現可能性についても論じる。
リアクティブプログラミングについて
- 時変値(ジヘンチ, time-varying values)を抽象化
- 現在時刻のようなもの
- ストリームのようなもの イベント列とか
- 宣言的につなげていく
- データフローになる
- リアクティブシステムになる
- センサーとモーターの連携とか
- 例題: ストップウォッチ
- ふつうにJavaで書くと状態遷移がわかりにくい。
- 仕様がまざりあってしまう。
- stopwatch as a flow b/w TVVs
button → activation → label │ │ └→ ↓ time → counter
- abstractions of TVV in RP
- FRP: behavior(連続的変化), event(離散)
- Reactive extension (RxJavaとか)
- SignalJ
- デザインスペース
- evaluation strategy: push-based or pull-based
- pushはイベントドリブンにあうがglitchの問題がある
- pullはglitchはないが即時反映に向かない
- lifting
- 既存の言語(Host言語)の上に拡張した場合、変換をどうするか?
- lift: f(T) -> f_lifted(TVV
) - explicit: lift(f)(b) -> flifted(b)
- implicit: f(b) -> flifted(b)
- glitch avoidance
- 値が伝搬するときの一時的な不整合 (1つの値が複数の経路を経由して結果に影響する場合)
- 気にしないという考えかたもある
- トポロジカルソートが必要(push-basedの場合)
- 分散システムだと解決は困難
- support for switching propagation
- 伝搬システムを動的に切り替えたい(値によって切り替えたい)l
- support for distribution
- webとかmobileとかでRPをつかったらconsistencyを維持するのがむつかしい
- コーディネータにまかせて解決するとか
- RPのアルゴリズムを分散システムに対応させるか
- evaluation strategy: push-based or pull-based
SignalJ: a simple Java-based RP language
- 特徴:
- シンプルなプログラミングインタフェース = シグナルという抽象化のみ、liftがない(signalを値として使える)
- push, glitch-free, switching support, side-effects
- 例:
signal int a = 5; // "signal"はmodifier; source signal signal int b = a + 3; // composite signal; 再代入は禁止 a++; System.out.println(b); // 9
- 例:
signal int a = 5; a.subscribe(e -> System.out.println(e)); // イベントハンドラ a++;
- 例:
signal int a = 5; a++; System.out.println(a.sum()); // 11
- 評価戦略
- 変化に(論理的な)時間はかからないとする
- mostly pull-based. 必要なときだけ計算 (folding演算はしかたなくeagerly)
- イベントハンドラの実行は(論理的な)時間が進む. 値が確定してから評価される
- シグナルネットワーク切り替え = オブジェクトのシグナル
signal int tabIndex = 0; List tabs = List().add(new View()); signal View currentView = tabs.getViewByInde(tabIndex);
- 時変値は即座に反映するだけでなく永続化もしたい
- 車輌トラッキングの例
- x,y座標の変化から速度を計算
- 永続シグナル: persistent signal double posX, posY;
- 伝搬はDBでのviewにあたる
- 問題: 複合的なデータ構造を表現できない(例だとx,y別々にsinalを割り当ている)、同時であることの保証はプログラマの責任、、、、
- Signal Classの導入で解決
- 関係するsignalをまとめたパッケージみたいなもの
- 同期とライフサイクルの単位になる
Vehicle mirror = new Vihicle("xx"); mirror.snapshot(slider.getValue()); Timer t= new Timer(v, 10000, v::setPosition); // push=based
[2021-02-24 16:12]
- Q: 予期せずsignalになっていて負荷がかかってしまうようなことはないか?
- A: modifierではなくannotationにする案もあったが、明示的に書くようにした。IDEのサポートで変数がsignalかどうかがわかるようにできるとおもう。
- Q: でかいDB(機械学習の大きいデータセット数TBあるような)はいっぱつで作れなくて、アップデートに何日もかかったりするきに、リアクティブにできないか? 例えばデータセットのバージョンをv1からv1.1に上げるときにデータセットをつかった再計算をリアクティブにできないか?
- A: signal classの実装変更の相当するか。今後の検討課題。
- Q: signaljがno liftingということだがimplicit liftingとはちがうのか?
- A: implicitといってもかまわない。liftingを意識する必要がない(言語的にはliftingを用意していない)。内部的にはliftingをしている。
- Q: signalは適切な抽象化になっているということだが、プログラムの検証はしやすくなっているか?
- A: あまり考えていない。
- Q: signaljの実装はどうなっている?
- A: source-to-source。RxJavaのランタイムをラップするかたちでつかっている。
- Q: 分散RPでの検証はどうなっている? (DBのconsistencyがとれている前提で)
- A: これからのテーマではないか。
- Q: セキュリティ・プライバシーについて
- A: クローズドなシステムでつかわれているだけなので、これからのテーマ。分散化がはじまったところなのでこれからのテーマか。
[2021-02-24 16:40]