SlideShare a Scribd company logo
「再代入なんて、あるわけない」
~ふつうのプログラマが関数型言語を知るべき理由~

                     There is no reassignment.


     Present by ぱろっと(@parrot_studio)
                   for Gunma.web #5
                        2011/05/14
Profile


Twitter : @parrot_studio
hatena/github : parrot_studio
第1話
「参照透明性も、遅延評価も、あるんだよ」

   Referential transparency and Lazy evaluation is here.
関数型言語
=数学の概念を実装したもの
関数型言語の
代表的な特性を3つ
  (´・ω・)っ
数学で

     s=α+β
  とか置いてから、後で

     s=αβ
と置きなおすなんてことはしない
   (s’=αβならある)
「s」は変数ではなく、
「α+β」に名前を「定義」しただけ
 (関数型では「束縛」と表現する)
It’s   再代入不可
だから「i += 1」なんてできない
CやJSのようなfor文は書けない

     Σ(゚Д゚)ガーン
=> 「再帰」「List処理」等を使う
逆に、こんなことは考えなくていい
 @a = 2 # 変数aに2を代入

 def f(x) # 変数aに加算して返す関数
  @a + x
 end

 puts f(2) #=> 2+2=4

 # 何か長い処理
 # 途中で @a=5 とかされるかも?

 puts f(2) # この値はいくつ(´・ω・)?
再代入ができない
=f(x)の値はxが決まれば一意に決まる
   (関数の呼び出しに副作用がない)
じゃあ、f(2)=4なら、

f(2)を4に全部置き換えていいよね?
It’s   参照透明性
“いつ”計算しても同じ値になるなら、

「必要になったら」計算しても
     同じだよね?
It’s   遅延評価
f(x) = (x-1)(なんか難しい式)
    のとき、f(1) = 0 は
後ろを計算しなくてもわかるよね?
でも・・・
俗に言う「関数型言語」が、
この3つを「全部」もっているかというと、
   そうでもないΣ(・ω・ノ)ノ
純関数型      全部「強制」
          例:Haskell
関数型       どれかが欠けているとか、オプション
          例:Scala/Erlang/OCaml
関数型風記述    関数型っぽく書ける
          例:最近流行の言語(Ruby/JS/C#等)
手続き型      関数型っぽく書くこと自体が難しい
          例:C/Java/Perl

         ※分類方法は個人的に考えた適当なものです
なぜ「関数型風」に書けると嬉しいのか?
「関数型言語」を使うとどんなことができるのか?
第2話
「宣言的なのはとっても嬉しいなって」

         It is very glad to declarative..
関数型(風)のコード
=「定義(define)」の連鎖
関数型っぽく書いたRubyのコード

def room_blocks
 blocks.select(&:has_room?)
end

def rooms
 room_blocks.collect(&:room)
end

def start_point
 rooms.sample(1).random_point
end
「手続き」ではなく
  「宣言・定義」
=「これは~です」が並ぶ
def room_blocks
 blocks.select(&:has_room?)
end

room_blocks とは blocksの中で
roomを持っているものを選んだものである
def rooms
 room_blocks.collect(&:room)
end

rooms とは room_blocks のroomを
集めたものである
def start_point
 rooms.sample(1).random_point
end

start_point とは roomsの中から
一つサンプリングして、
ランダムな座標を選んだものである
一つ一つの「定義」は小さいから、
個別のテスト(spec)も書きやすい
      (`・ω・´) b
あえて手続きで書くと・・・
 def room_blocks
  ret = []
  for i in (0..blocks.size)
    if blocks[i].has_room?
      ret << blocks[i]
    end
  end
  return ret
 end
「やりたいこと」が埋もれるので、
「読みやすい」というのは非常に重要
”名前重要” by matz
 「97きのこ」:J10 / 「コードの世界」:P150
第3話
「もうデッドロックは怖くない」

        Deadlock not afraid anymore.
関数の値が入力だけで決まるなら、
「いつ」「どこで」処理しても結果は同じ
なら、並列処理してもいいよね
    (´・ω・)?
並列処理手法の一つ:アクターモデル
アクターモデルの話だけで
LTどころではない時間を食うので、
     簡単に説明
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)
アクターモデルの場合

    この処理を頼みたいんだが・・・

        あーそこのBOXに入れておいてください
        後でやっておきます


...φ(・ω・`)   各自の処理            ...φ(・ω・`)

              頼まれた処理終わりましたよ


    じゃあ、私のBOXに入れておいてくれ
    後で確認する



...φ(・ω・`)    各自の処理           ...φ(・ω・`)
「値」は「入力」によって決まり、
   「状態」に依存しないから、
アクター間で「状態」を共有する必要がない
      =ロックが不要
詳しくは・・・

ScalaのアクターモデルでMapReduce処理を書いてみる
    d.hatena.ne.jp/parrot_studio/20110205/1296880522
第4話
「本当の副作用と向き合えますか?」

     Can it be opposite to a true side effect?
関数型の概念自体は60年代からあるが、
   「時代」が関数型を求め始めた
 マルチコアCPU / サーバクラスタ(Hadoop等)
ほっといてもCPUは速くならない
プログラマが工夫する時代へ
  「フリーランチの終焉」
     matz@日経Linux 2011/05
もはや、
  「普通のプログラマ」と
関数型は無関係ではないかもしれない
実は、関数型の概念は理想的なもの
「画面に表示する」
  「DBやファイルからデータを読む」

どれもリソースに依存して結果が変わる
     =副作用がある
できるだけ副作用のある箇所を
局所的にして、切り離すことが重要
「読みやすく」「副作用の少ない」

関数型の概念を学んでみませんか
     (´・ω・)?
ありがとうございました
  (´・ω・)っ旦~
参考文献
【おまけ】
そもそも、Rubyは
「綺麗に書くほど速い=最適化される」
       言語
Rubyで先ほどのような
   for文はまず使わない
確実に「もっと美しい書き方」がある
Rubyを「知る」には
実は関数型の概念がいる


私がRubyのありがたさを実感したのは
  「ふつうのHaskell」を読んだ後
実際、関数型として書いたRubyと
元々関数型のScalaのコードは
   非常によく似ている
コマ大数学科の問題をRubyとScalaで解いてみる
    d.hatena.ne.jp/parrot_studio/20110302/1299051431

More Related Content

「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)