20150131 mvp com_camp_lt
TRANSCRIPT
非関数型プログラマにおくるデータフロー図のすゝめ真鍋俊之
まとめ
• 副作用のあるプログラムは複雑になりやすい
• 副作用が少ないプログラムは、▫ モジュール性が高まる
▫ テストが簡単になる
▫ 並列化しやすくなる
• データフロー図を用いた設計を行うことで、副作用の少ないプログラムができる、かも
関数型プログラミング
• 副作用をできるだけ用いないプログラミングスタイル
• 副作用とは、▫ 「式の値を計算して求める(評価)」以外の動作
引用:Qiita「関数型言語」に関するFAQ形式の一般的説明http://qiita.com/esumii/items/ec589d138e72e22ea97e
副作用のない関数例
• int add ( int a, int b ) {
return a + b;}
副作用のある関数例
• int add ( int a, int b ) {printf ( “%d”, a );return a + b;
}
• 「 printf ( “%d”, a ); 」の行で画面に出力している。▫ 「画面に表示する」という副作用を含んでいる。
副作用がないことで何が嬉しい?
• 関数の出力が入力にのみに依存する(=文脈によって、結果が変わらない)▫ 関数の独立性が高い
▫ テスト、検証が容易
▫ 人が理解しやすい
オブジェクト指向と関数型プログラミング• 「オブジェクト指向は副作用の分割統治を、
関数型プログラミングは副作用の排除を行うことで、モジュール性を高めようとしたと考えられます。」
引用:なぜリアクティブプログラミングは重要か。http://d.hatena.ne.jp/pokarim/20101226
関数型プログラミングは難しい?
• 難しい話が多い▫ 再帰関数
▫ 高階関数
▫ 参照透明性
▫ 遅延評価
▫ モナド
▫ 型推論
なぜ、データフロー図を使うのか
• 設計なので、関数型(プログラミング)言語を使わない人でも利用可能
• 副作用のない関数を考える目的でも使える
処理データ データ
データフロー図の書き方
• データと処理を矢印でつなげる。
• 「データ⇒処理」はデータが処理の入力であることを示す
• 「処理⇒データ」はデータが処理の出力であることを示す
• 処理は副作用がないように、必要なデータはできる限り書く
処理
入力 出力
データ データ
データフロー図の何が嬉しいのか
• どの順序でデータを作ればよいか(≒処理順序)が分かりやすくなる
• 並列に実行できるところが分かる
処理
処理
データ
データ
データ
データ
処理 データ並列に実行可能
実例:ライフゲーム(1/2)
• 碁盤のような格子があり、一つの格子はセル(細胞)と呼ばれる。
• 各セルには8つの近傍のセルがある (ムーア近傍)
• 各セルには「生」と「死」の2つの状態があり、あるセルの次のステップ(世代)の状態は周囲の8つのセルの今の世代における状態により決定される。
実例:ライフゲーム(2/2)
• セルの生死は次のルールに従う。• 誕生
▫ 死んでいるセルに隣接する生きたセルがちょうど3つあれば、次の世代が誕生する。
• 生存▫ 生きているセルに隣接する生きたセルが2つか3つならば、次の
世代でも生存する。
• 過疎▫ 生きているセルに隣接する生きたセルが1つ以下ならば、過疎に
より死滅する。
• 過密▫ 生きているセルに隣接する生きたセルが4つ以上ならば、過密に
より死滅する。
実例:ライフゲーム(2/2)
• セルの生死は次のルールに従う。• 誕生
▫ 死んでいるセルに隣接する生きたセルがちょうど3つあれば、次の世代が誕生する。
• 生存▫ 生きているセルに隣接する生きたセルが2つか3つならば、次の
世代でも生存する。
• 過疎▫ 生きているセルに隣接する生きたセルが1つ以下ならば、過疎に
より死滅する。
• 過密▫ 生きているセルに隣接する生きたセルが4つ以上ならば、過密に
より死滅する。
今のセルの状態と、隣接する生きたセルの数で次の世代の状態が決まる
世界 次の世代の世界
座標
セルの生死
隣接する生きているセルの数
次の世代のセルの生死
ルール
まとめる
隣接セル見る
セルの座標取得
セルの生死を見る
まとめ
• 副作用のあるプログラムは複雑になりやすい
• 副作用が少ないプログラムは、▫ モジュール性が高まる
▫ テストが簡単になる
▫ 並列化しやすくなる
• データフロー図を用いた設計を行うことで、副作用の少ないプログラムができる、かも