「再代入なんて、あるわけない」...

56
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ Present by ぱろっと(@parrot_studio) for Gunma.web #5 2011/05/14 There is no reassignment

Upload: parrotstudio

Post on 05-Dec-2014

16.228 views

Category:

Technology


0 download

DESCRIPTION

Gunma.web #5でやったLT資料実際のLT時には非表示にしていたページを含む

TRANSCRIPT

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

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

Present by ぱろっと(@parrot_studio)

for Gunma.web #5

2011/05/14

There is no reassignment.

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

Twitter : @parrot_studio

hatena/github : parrot_studio

Profile

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

第1話

「参照透明性も、遅延評価も、あるんだよ」

Referential transparency and Lazy evaluation is here.

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

関数型言語

=数学の概念を実装したもの

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

関数型言語の

代表的な特性を3つ

(´・ω・)っ

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

数学で

s=α+β

とか置いてから、後で

s=αβ

と置きなおすなんてことはしない

(s’=αβならある)

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

「s」は変数ではなく、

「α+β」に名前を「定義」しただけ

(関数型では「束縛」と表現する)

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

It’s 再代入不可

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

だから「i += 1」なんてできない

CやJSのようなfor文は書けない

Σ(゚Д゚)ガーン

=> 「再帰」「List処理」等を使う

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

@a = 2 # 変数aに2を代入 def f(x) # 変数aに加算して返す関数 @a + x end puts f(2) #=> 2+2=4 # 何か長い処理 # 途中で @a=5 とかされるかも? puts f(2) # この値はいくつ(´・ω・)?

逆に、こんなことは考えなくていい

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

再代入ができない

=f(x)の値はxが決まれば一意に決まる

(関数の呼び出しに副作用がない)

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

じゃあ、f(2)=4なら、

f(2)を4に全部置き換えていいよね?

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

It’s 参照透明性

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

“いつ”計算しても同じ値になるなら、

「必要になったら」計算しても

同じだよね?

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

It’s 遅延評価

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

f(x) = (x-1)(なんか難しい式)

のとき、f(1) = 0 は

後ろを計算しなくてもわかるよね?

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

でも・・・

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

俗に言う「関数型言語」が、

この3つを「全部」もっているかというと、

そうでもないΣ(・ω・ノ)ノ

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

純関数型 全部「強制」 例:Haskell

関数型 どれかが欠けているとか、オプション 例:Scala/Erlang/OCaml

関数型風記述 関数型っぽく書ける 例:最近流行の言語(Ruby/JS/C#等)

手続き型 関数型っぽく書くこと自体が難しい 例:C/Java/Perl

※分類方法は個人的に考えた適当なものです

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

なぜ「関数型風」に書けると嬉しいのか?

「関数型言語」を使うとどんなことができるのか?

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

第2話

「宣言的なのはとっても嬉しいなって」

It is very glad to declarative..

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

関数型(風)のコード

=「定義(define)」の連鎖

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

def room_blocks blocks.select(&:has_room?) end def rooms room_blocks.collect(&:room) end def start_point rooms.sample(1).random_point end

関数型っぽく書いたRubyのコード

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

「手続き」ではなく

「宣言・定義」

=「これは~です」が並ぶ

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

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

room_blocks とは blocksの中で

roomを持っているものを選んだものである

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

def rooms room_blocks.collect(&:room) end

rooms とは room_blocks のroomを

集めたものである

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

def start_point rooms.sample(1).random_point end

start_point とは roomsの中から

一つサンプリングして、

ランダムな座標を選んだものである

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

一つ一つの「定義」は小さいから、

個別のテスト(spec)も書きやすい

(`・ω・´) b

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

あえて手続きで書くと・・・

def room_blocks ret = [] for i in (0..blocks.size) if blocks[i].has_room? ret << blocks[i] end end return ret end

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

「やりたいこと」が埋もれるので、

「読みやすい」というのは非常に重要

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

”名前重要” by matz

「97きのこ」:J10 / 「コードの世界」:P150

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

第3話

「もうデッドロックは怖くない」

Deadlock not afraid anymore.

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

関数の値が入力だけで決まるなら、

「いつ」「どこで」処理しても結果は同じ

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

なら、並列処理してもいいよね

(´・ω・)?

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

並列処理手法の一つ:アクターモデル

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

アクターモデルの話だけで

LTどころではない時間を食うので、

簡単に説明

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

アクターモデルの場合

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

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

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

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

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

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

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

「値」は「入力」によって決まり、

「状態」に依存しないから、

アクター間で「状態」を共有する必要がない

=ロックが不要

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

詳しくは・・・

ScalaのアクターモデルでMapReduce処理を書いてみる

d.hatena.ne.jp/parrot_studio/20110205/1296880522

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

第4話

「本当の副作用と向き合えますか?」

Can it be opposite to a true side effect?

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

関数型の概念自体は60年代からあるが、

「時代」が関数型を求め始めた

マルチコアCPU / サーバクラスタ(Hadoop等)

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

ほっといてもCPUは速くならない

プログラマが工夫する時代へ

「フリーランチの終焉」

matz@日経Linux 2011/05

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

もはや、

「普通のプログラマ」と

関数型は無関係ではないかもしれない

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

実は、関数型の概念は理想的なもの

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

「画面に表示する」

「DBやファイルからデータを読む」

どれもリソースに依存して結果が変わる

=副作用がある

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

できるだけ副作用のある箇所を

局所的にして、切り離すことが重要

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

「読みやすく」「副作用の少ない」

関数型の概念を学んでみませんか

(´・ω・)?

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

ありがとうございました

(´・ω・)っ旦~

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

参考文献

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

【おまけ】

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

そもそも、Rubyは

「綺麗に書くほど速い=最適化される」

言語

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

Rubyで先ほどのような

for文はまず使わない

確実に「もっと美しい書き方」がある

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

Rubyを「知る」には

実は関数型の概念がいる

私がRubyのありがたさを実感したのは

「ふつうのHaskell」を読んだ後

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

実際、関数型として書いたRubyと

元々関数型のScalaのコードは

非常によく似ている

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

コマ大数学科の問題をRubyとScalaで解いてみる

d.hatena.ne.jp/parrot_studio/20110302/1299051431