start frp

47
Functional Reactive Programming はじめの一歩 配線プログラミング @rf0444

Upload: rf0444

Post on 10-Jun-2015

3.931 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Start FRP

Functional Reactive Programming はじめの一歩~ 配線プログラミング ~

@rf0444

Page 2: Start FRP

おしながき

•スプレッドシートの話

•配線プログラミング

Page 3: Start FRP

スプレッドシートの話

Page 4: Start FRP

スプレッドシート?

Page 5: Start FRP

スプレッドシート?

スプレッドシートでは当たり前の、ある機能のお話をします。

Page 6: Start FRP

一般的なプログラム

JavaScript

Page 7: Start FRP

一般的なプログラム

JavaScript

Page 8: Start FRP

4 になってほしいケース

•値の変更があったら、関連する値も更新されて欲しい

•リアルタイムアプリケーション

• GUI

Page 9: Start FRP

スプレッドシートの場合

Page 10: Start FRP

スプレッドシートの場合

Page 11: Start FRP

スプレッドシートの場合

Page 12: Start FRP

スプレッドシートの場合

Page 13: Start FRP

JavaScript での実装例  - イベント駆動

function onChange() { var a = Number($("#val1").val()); var b = Number($("#val2").val()); var c = a + b; $("#val3").text(c);}$("#val1").change(onChange);$("#val2").change(onChange);

Page 14: Start FRP

JavaScript での実装

•イベント駆動プログラミング

•変化が起きたときに実行する「処理」を書いていく

•手続き的アプローチ

• Any other approach?

Page 15: Start FRP

配線プログラミング

Page 16: Start FRP

スプレッドシート と 配線 のイメージ

A1

B1

C1+

Page 17: Start FRP

JavaScript での実装を考える

a

b

c+

Page 18: Start FRP

Bacon.js

• JavaScript ライブラリ

•配線プログラミング をサポート

• jQuery と連携できる

•他の JavaScript フレームワークとも連携できる

• backbone.js との連携例あり

Page 19: Start FRP

配線をつくる

a

b

c+

Page 20: Start FRP

配線をつくる

a

b

c

Page 21: Start FRP

配線をつくる

a

b

cBus

Bus Bus

function Model() { var me = this; me.a = new Bacon.Bus(); me.b = new Bacon.Bus(); me.c = new Bacon.Bus(); }

Page 22: Start FRP

配線をつくる

a

b

c

function Model() { var me = this; me.a = new Bacon.Bus(); me.b = new Bacon.Bus(); me.c = new Bacon.Bus(); }

Page 23: Start FRP

+

配線をつくる

a

b

c

function Model() { var me = this; me.a = new Bacon.Bus(); me.b = new Bacon.Bus(); me.c = new Bacon.Bus(); Bacon.combineWith(function(a, b) { return a + b; }, me.a, me.b) }

Page 24: Start FRP

配線をつくる

+a

b

c

function Model() { var me = this; me.a = new Bacon.Bus(); me.b = new Bacon.Bus(); me.c = new Bacon.Bus(); Bacon.combineWith(function(a, b) { return a + b; }, me.a, me.b).change() }

Page 25: Start FRP

配線をつくる

+a

b

c

function Model() { var me = this; me.a = new Bacon.Bus(); me.b = new Bacon.Bus(); me.c = new Bacon.Bus(); me.c.plug( Bacon.combineWith(function(a, b) { return a + b; }, me.a, me.b).change() );}

Page 26: Start FRP

入力側をつなげる

+

a

b

c

Page 27: Start FRP

入力側をつなげる

+

a

b

c

Page 28: Start FRP

入力側をつなげる

a

Page 29: Start FRP

入力側をつなげる

busel

function InputView(el, bus) { var me = this; me.el = el; }

a

Page 30: Start FRP

入力側をつなげる

function InputView(el, bus) { var me = this; me.el = el; me.el.asEventStream("change") }

a

Page 31: Start FRP

入力側をつなげる

(change event)

function InputView(el, bus) { var me = this; me.el = el; me.el.asEventStream("change") }

a

Page 32: Start FRP

入力側をつなげる

“1”

function InputView(el, bus) { var me = this; me.el = el; me.el.asEventStream("change") .map(function() { return me.el.val(); }) }

a

Page 33: Start FRP

入力側をつなげる

“1”初期値 ( “0” )

function InputView(el, bus) { var me = this; me.el = el; me.el.asEventStream("change") .map(function() { return me.el.val(); }) .merge(Bacon.once(me.el.val())) }

a“1” “0”

Page 34: Start FRP

入力側をつなげる

“1”初期値 ( “0” )

function InputView(el, bus) { var me = this; me.el = el; me.el.asEventStream("change") .map(function() { return me.el.val(); }) .merge(Bacon.once(me.el.val())) .map(Number) }

a“1” “0” 1 0

Page 35: Start FRP

入力側をつなげる

a

function InputView(el, bus) { var me = this; me.el = el; bus.plug( me.el.asEventStream("change") .map(function() { return me.el.val(); }) .merge(Bacon.once(me.el.val())) .map(Number) );}

“1”初期値 ( “0” ) 1 0“1” “0”

Page 36: Start FRP

出力側をつなげる

+

a

b

c

Page 37: Start FRP

出力側をつなげる

+

a

b

c

Page 38: Start FRP

出力側をつなげる

c

function OutputView(el, bus) { var me = this; me.el = el; }

busel

Page 39: Start FRP

出力側をつなげる

c

function OutputView(el, bus) { var me = this; me.el = el; bus.assign(function(val) { });}

val

Page 40: Start FRP

出力側をつなげる

c

function OutputView(el, bus) { var me = this; me.el = el; bus.assign(function(val) { me.el.text(val); });}

val

Page 41: Start FRP

完成

var model = new Model();new InputView($("#a"), model.a);new InputView($("#b"), model.b);new OutputView($("#c"), model.c);

a b c

model

+

Page 42: Start FRP

部品プログラミング

「他の言語を学んで自由になろう」(山本和彦, http://mew.org/~kazu/material/2013-lang.pdf) より引用

Page 43: Start FRP

部品プログラミング

「他の言語を学んで自由になろう」(山本和彦, http://mew.org/~kazu/material/2013-lang.pdf) より引用

Page 44: Start FRP

部品プログラミング との組み合わせ

model

view1(editable)

view2

Page 45: Start FRP

設計例

View

Model

StorageAjax

request event for model

request to server response from server

response event for model

Page 46: Start FRP

Functional Reactive Programming (FRP)

• 下の 2 つを関数でつないでいくことで、プログラムを書いていく方法

• 時間によって変化する値 (Behavior)

• 発生するイベントの列 (Event)

• GUI だけでなく、ログなどのリアルタイム解析でも利用されている

• 「配線プログラミング」は、実は FRP のこと

Page 47: Start FRP

利用ライブラリ

• Bacon.js

• https://github.com/raimohanska/

• Behavior → Property、Event → EventStream