副作用

Hokuriku.                          第一回

   西本圭佑 (NISHIMOTO Keisuke)
       keisuken@cappuccino.ne.jp
自己紹介
 ➔   緒言
      ➔
             西本 圭佑
      ➔      NISHIMOTO Keisuke
      ➔      keisuken@cappuccino.ne.jp
      ➔     ...
自己紹介
 ➔   趣味
      ➔      プログラミング(なんでも)
      ➔      電子工作
      ➔      鉄道全般: 乗ること, 調べること
             ➔
                 今...
自己紹介

 ➔   今月は勉強会デー、順次北上中...
      ➔      9/12 岡山: オープンラボ岡山
             ➔   ScalaでAndroidアプリケーションの開発
      ➔      9/19 京都...
副作用とは
 ➔   プログラミングにおける副作用とは、ある機能がコ
     ンピュータの(論理的な)状態を変化させ、それ以降
     で得られる結果に影響を与えること
      ➔      Wikipedia - 副作用 (プログラム...
副作用とは

 ➔   参照透過性 (Referential transparency)
      ➔      文脈によらず式の値はその構成要素(変数や関数など)
             によってのみ定まるということ
      ➔
  ...
副作用とは
 ➔   副作用を伴う例
      ➔      I/O制御(write/print等)、
      ➔      破壊的代入
             ➔   ノイマン型のアーキテクチャは副作用を前提として動作する
     ...
副作用を排除すると
 ➔   長所
      ➔
             いかなる状況でも常に同じ結果が得られるために、機
             能を純粋にアルゴリズムとして定義でき、状況依存での
             バグの発生が...
例: フィボナッチ数列
 ➔   フィボナッチ数列の式
      ➔      F0 = 0, F1 = 1
      ➔      Fn+2 = Fn + Fn+1 (n >= 0)
             ➔   0, 1, 1, 2...
例: フィボナッチ数列

 ➔   副作用のないコード(Scala)
             def fib(n: Int): Int =
               if (n < 2) n
               else fib...
例: フィボナッチ数列

 ➔   副作用のあるコード(Scala)
             def fib(n: Int): Int = {
               if (n < 2) n
               else {...
例: フィボナッチ数列

 ➔   副作用のあるコード(Java)
             public int fib(int n) {
               if (n < 2) return n;
               ...
例: フィボナッチ数列
 ➔   副作用のあるコード
      ➔      ループ変数(破壊的代入)
      ➔      参照透過性がない(状態が書き換わる)
             ➔   状態の書き換えの順番は重要(因果律)
 ...
Scalaで副作用を取り除くには
 ➔   文法
      ➔      再代入できない変数: val
              val str1 =   "Hello"
              val str2 =   "world"...
Scalaで副作用を取り除くには
 ➔   文法
      ➔      すべてが式: if, match, try catch, ...
               val str = "1234"
               val ...
Scalaで副作用を取り除くには
 ➔   文法
      ➔
             再帰呼び出し
             ➔   再帰呼び出しの最適化(末尾再帰)

                 val start = 1
   ...
Scalaで副作用を取り除くには

 ➔   API
      ➔      繰り返しユーティリティメソッド: map, filter, ...
               List(1, 2, 3).map {i => i * 2}
  ...
Scalaで副作用を取り除くには

➔   API
    ➔   Immutableなコレクション:
        scala.collection.immutable._
          import scala.collection...
まとめ
 ➔   副作用をなくすといいことがある
      ➔      (状態がないので)シンプルになるかもしれない
      ➔      (状態がないので)バグが抑えられるかもしれない
 ➔   副作用をなくすことによる問題
    ...
おわり




             ご清聴ありがとうございました




2009/09/26      Hokuriku.Scala 第一回   20
質疑応答




             Any Questions?




2009/09/26      Hokuriku.Scala 第一回   21
Upcoming SlideShare
Loading in …5
×

Hokuriku Scala 1

1,563 views

Published on

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,563
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
12
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Hokuriku Scala 1

  1. 1. 副作用 Hokuriku. 第一回 西本圭佑 (NISHIMOTO Keisuke) keisuken@cappuccino.ne.jp
  2. 2. 自己紹介 ➔ 緒言 ➔ 西本 圭佑 ➔ NISHIMOTO Keisuke ➔ keisuken@cappuccino.ne.jp ➔ Twitter: keisuke_n ➔ 仕事 ➔ Webアプリケーションの開発・支援 ➔ それにかかわる導入・運用 2009/09/26 Hokuriku.Scala 第一回 2
  3. 3. 自己紹介 ➔ 趣味 ➔ プログラミング(なんでも) ➔ 電子工作 ➔ 鉄道全般: 乗ること, 調べること ➔ 今日は、新幹線にサンダーバードを堪能 ➔ 使用言語 ➔ Java, Ruby, JavaScript, ActionScript, C#, PHP ➔ そして Scala 2009/09/26 Hokuriku.Scala 第一回 3
  4. 4. 自己紹介 ➔ 今月は勉強会デー、順次北上中... ➔ 9/12 岡山: オープンラボ岡山 ➔ ScalaでAndroidアプリケーションの開発 ➔ 9/19 京都: Ruby/Rails勉強会@関西 ➔ 自作ハードウェアをRubyから操作 ➔ 9/26 富山: Hokuriku.Scala ➔ 副作用について語る 2009/09/26 Hokuriku.Scala 第一回 4
  5. 5. 副作用とは ➔ プログラミングにおける副作用とは、ある機能がコ ンピュータの(論理的な)状態を変化させ、それ以降 で得られる結果に影響を与えること ➔ Wikipedia - 副作用 (プログラム)より ➔ 副作用によって参照透過性が失われる 2009/09/26 Hokuriku.Scala 第一回 5
  6. 6. 副作用とは ➔ 参照透過性 (Referential transparency) ➔ 文脈によらず式の値はその構成要素(変数や関数など) によってのみ定まるということ ➔ 変数の値は最初に定義した値と常に同じであり、関数 の引数が同じ値であれば同じ値を返す ➔ 変数に値を割り当てなおす代入がない ➔ 参照透過性が成り立っている場合、ある式の値、例え ば関数値、変数値についてどこに記憶されているか参 照しているかを考慮する必要がない、即ち参照につい て透過的である ➔ Wikipedia - 参照透過性より 2009/09/26 Hokuriku.Scala 第一回 6
  7. 7. 副作用とは ➔ 副作用を伴う例 ➔ I/O制御(write/print等)、 ➔ 破壊的代入 ➔ ノイマン型のアーキテクチャは副作用を前提として動作する ため、多くのプログラミング言語では変数の破壊的代入機能 を持つ。 ➔ 副作用を伴わない例 ➔ 破壊的代入を行わない ➔ 定数 ➔ 変数をその処理の範囲では定数として扱う(再代入されない) ➔ モナドによる副作用の抽象化 2009/09/26 Hokuriku.Scala 第一回 7
  8. 8. 副作用を排除すると ➔ 長所 ➔ いかなる状況でも常に同じ結果が得られるために、機 能を純粋にアルゴリズムとして定義でき、状況依存での バグの発生が抑えられる ➔ 短所 ➔ ノイマン型アーキテクチャと反りが合わず、効率の点で 不利になることが多い ➔ 単純な逐次処理を行う場合は状態を中心に命令的な 思考をした方が扱いやすい場合がある 2009/09/26 Hokuriku.Scala 第一回 8
  9. 9. 例: フィボナッチ数列 ➔ フィボナッチ数列の式 ➔ F0 = 0, F1 = 1 ➔ Fn+2 = Fn + Fn+1 (n >= 0) ➔ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, … ➔ プログラムで使いやすい形に変換 ➔ F0 = 0, F1 = 1 ➔ Fn = Fn-2 + Fn-1 (n >= 2) 2009/09/26 Hokuriku.Scala 第一回 9
  10. 10. 例: フィボナッチ数列 ➔ 副作用のないコード(Scala) def fib(n: Int): Int = if (n < 2) n else fib(n-2) + fib(n-1) ➔ 再帰呼び出し ➔ 式による表現 ➔ 状態変数なし(参照透過性) 2009/09/26 Hokuriku.Scala 第一回 10
  11. 11. 例: フィボナッチ数列 ➔ 副作用のあるコード(Scala) def fib(n: Int): Int = { if (n < 2) n else { var fnm2 = 0; var fnm1 = 1; var fn = 0 for (i <- 2 to n) { fn = fnm2 + fnm1 fnm2 = fnm1; fnm1 = fn } fn } } 2009/09/26 Hokuriku.Scala 第一回 11
  12. 12. 例: フィボナッチ数列 ➔ 副作用のあるコード(Java) public int fib(int n) { if (n < 2) return n; else { int fnm2 = 0; int fnm1 = 1; int fn = 0; for (int i = 2; i <= n; i++) { fn = fnm2 + fnm1; fnm2 = fnm1; fnm1 = fn; } return fn; } } 2009/09/26 Hokuriku.Scala 第一回 12
  13. 13. 例: フィボナッチ数列 ➔ 副作用のあるコード ➔ ループ変数(破壊的代入) ➔ 参照透過性がない(状態が書き換わる) ➔ 状態の書き換えの順番は重要(因果律) ➔ 状態を表す変数がたくさん作られる ➔ (この例では)見通しが悪い 2009/09/26 Hokuriku.Scala 第一回 13
  14. 14. Scalaで副作用を取り除くには ➔ 文法 ➔ 再代入できない変数: val val str1 = "Hello" val str2 = "world" val result = str1 + ", " + str2 + "!" // "Hello, world!" 2009/09/26 Hokuriku.Scala 第一回 14
  15. 15. Scalaで副作用を取り除くには ➔ 文法 ➔ すべてが式: if, match, try catch, ... val str = "1234" val result = try { str.toInt } catch { case NumberFormatException => -1 } // result = 1234 2009/09/26 Hokuriku.Scala 第一回 15
  16. 16. Scalaで副作用を取り除くには ➔ 文法 ➔ 再帰呼び出し ➔ 再帰呼び出しの最適化(末尾再帰) val start = 1 val end = 10 def sum(i: Int, v: Int): Int = if (i <= end) sum(i + 1, v + i) else v val result = sum(start, 0) // 55 2009/09/26 Hokuriku.Scala 第一回 16
  17. 17. Scalaで副作用を取り除くには ➔ API ➔ 繰り返しユーティリティメソッド: map, filter, ... List(1, 2, 3).map {i => i * 2} // List(2, 4, 6) Array(1, 2, 3, 4).filter {_ % 2 == 0} // Array(2, 4) List(1, 2, 3, 4, 5).takeWhile {_ <= 3} // List(1, 2, 3) (1 to 10).foldLeft(0) {(sum, a) => sum + a} // 55 2009/09/26 Hokuriku.Scala 第一回 17
  18. 18. Scalaで副作用を取り除くには ➔ API ➔ Immutableなコレクション: scala.collection.immutable._ import scala.collection.immutable.HashMap val map1 = HashMap('a -> 1, 'b -> 2) val map2 = map1 + ('c -> 3) // map1: HashMap('a->1, 'b->2) // map2: HashMap('a->1, 'b->2, 'c->3)
  19. 19. まとめ ➔ 副作用をなくすといいことがある ➔ (状態がないので)シンプルになるかもしれない ➔ (状態がないので)バグが抑えられるかもしれない ➔ 副作用をなくすことによる問題 ➔ 場合によっては複雑になるかもしれない ➔ 特に逐次処理 ➔ Scalaには副作用を抑えるサポートがある 2009/09/26 Hokuriku.Scala 第一回 19
  20. 20. おわり ご清聴ありがとうございました 2009/09/26 Hokuriku.Scala 第一回 20
  21. 21. 質疑応答 Any Questions? 2009/09/26 Hokuriku.Scala 第一回 21

×