![Page 1: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/1.jpg)
「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~
Present by ぱろっと(@parrot_studio)
for Gunma.web #5
2011/05/14
There is no reassignment.
![Page 2: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/2.jpg)
Twitter : @parrot_studio
hatena/github : parrot_studio
Profile
![Page 3: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/3.jpg)
第1話
「参照透明性も、遅延評価も、あるんだよ」
Referential transparency and Lazy evaluation is here.
![Page 4: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/4.jpg)
関数型言語
=数学の概念を実装したもの
![Page 5: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/5.jpg)
関数型言語の
代表的な特性を3つ
(´・ω・)っ
![Page 6: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/6.jpg)
数学で
s=α+β
とか置いてから、後で
s=αβ
と置きなおすなんてことはしない
(s’=αβならある)
![Page 7: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/7.jpg)
「s」は変数ではなく、
「α+β」に名前を「定義」しただけ
(関数型では「束縛」と表現する)
![Page 8: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/8.jpg)
It’s 再代入不可
![Page 9: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/9.jpg)
だから「i += 1」なんてできない
CやJSのようなfor文は書けない
Σ(゚Д゚)ガーン
=> 「再帰」「List処理」等を使う
![Page 10: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/10.jpg)
@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)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/11.jpg)
再代入ができない
=f(x)の値はxが決まれば一意に決まる
(関数の呼び出しに副作用がない)
![Page 12: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/12.jpg)
じゃあ、f(2)=4なら、
f(2)を4に全部置き換えていいよね?
![Page 13: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/13.jpg)
It’s 参照透明性
![Page 14: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/14.jpg)
“いつ”計算しても同じ値になるなら、
「必要になったら」計算しても
同じだよね?
![Page 15: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/15.jpg)
It’s 遅延評価
![Page 16: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/16.jpg)
f(x) = (x-1)(なんか難しい式)
のとき、f(1) = 0 は
後ろを計算しなくてもわかるよね?
![Page 17: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/17.jpg)
でも・・・
![Page 18: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/18.jpg)
俗に言う「関数型言語」が、
この3つを「全部」もっているかというと、
そうでもないΣ(・ω・ノ)ノ
![Page 19: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/19.jpg)
純関数型 全部「強制」 例:Haskell
関数型 どれかが欠けているとか、オプション 例:Scala/Erlang/OCaml
関数型風記述 関数型っぽく書ける 例:最近流行の言語(Ruby/JS/C#等)
手続き型 関数型っぽく書くこと自体が難しい 例:C/Java/Perl
※分類方法は個人的に考えた適当なものです
![Page 20: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/20.jpg)
なぜ「関数型風」に書けると嬉しいのか?
「関数型言語」を使うとどんなことができるのか?
![Page 21: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/21.jpg)
第2話
「宣言的なのはとっても嬉しいなって」
It is very glad to declarative..
![Page 22: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/22.jpg)
関数型(風)のコード
=「定義(define)」の連鎖
![Page 23: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/23.jpg)
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)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/24.jpg)
「手続き」ではなく
「宣言・定義」
=「これは~です」が並ぶ
![Page 25: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/25.jpg)
def room_blocks blocks.select(&:has_room?) end
room_blocks とは blocksの中で
roomを持っているものを選んだものである
![Page 26: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/26.jpg)
def rooms room_blocks.collect(&:room) end
rooms とは room_blocks のroomを
集めたものである
![Page 27: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/27.jpg)
def start_point rooms.sample(1).random_point end
start_point とは roomsの中から
一つサンプリングして、
ランダムな座標を選んだものである
![Page 28: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/28.jpg)
一つ一つの「定義」は小さいから、
個別のテスト(spec)も書きやすい
(`・ω・´) b
![Page 29: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/29.jpg)
あえて手続きで書くと・・・
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)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/30.jpg)
「やりたいこと」が埋もれるので、
「読みやすい」というのは非常に重要
![Page 31: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/31.jpg)
”名前重要” by matz
「97きのこ」:J10 / 「コードの世界」:P150
![Page 32: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/32.jpg)
第3話
「もうデッドロックは怖くない」
Deadlock not afraid anymore.
![Page 33: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/33.jpg)
関数の値が入力だけで決まるなら、
「いつ」「どこで」処理しても結果は同じ
![Page 34: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/34.jpg)
なら、並列処理してもいいよね
(´・ω・)?
![Page 35: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/35.jpg)
並列処理手法の一つ:アクターモデル
![Page 36: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/36.jpg)
アクターモデルの話だけで
LTどころではない時間を食うので、
簡単に説明
![Page 37: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/37.jpg)
![Page 38: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/38.jpg)
アクターモデルの場合
この処理を頼みたいんだが・・・
あーそこのBOXに入れておいてください 後でやっておきます
頼まれた処理終わりましたよ
じゃあ、私のBOXに入れておいてくれ 後で確認する
...φ(・ω・`) 各自の処理 ...φ(・ω・`)
...φ(・ω・`) 各自の処理 ...φ(・ω・`)
![Page 39: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/39.jpg)
「値」は「入力」によって決まり、
「状態」に依存しないから、
アクター間で「状態」を共有する必要がない
=ロックが不要
![Page 40: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/40.jpg)
詳しくは・・・
ScalaのアクターモデルでMapReduce処理を書いてみる
d.hatena.ne.jp/parrot_studio/20110205/1296880522
![Page 41: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/41.jpg)
第4話
「本当の副作用と向き合えますか?」
Can it be opposite to a true side effect?
![Page 42: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/42.jpg)
関数型の概念自体は60年代からあるが、
「時代」が関数型を求め始めた
マルチコアCPU / サーバクラスタ(Hadoop等)
![Page 43: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/43.jpg)
ほっといてもCPUは速くならない
プログラマが工夫する時代へ
「フリーランチの終焉」
matz@日経Linux 2011/05
![Page 44: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/44.jpg)
もはや、
「普通のプログラマ」と
関数型は無関係ではないかもしれない
![Page 45: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/45.jpg)
実は、関数型の概念は理想的なもの
![Page 46: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/46.jpg)
「画面に表示する」
「DBやファイルからデータを読む」
どれもリソースに依存して結果が変わる
=副作用がある
![Page 47: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/47.jpg)
できるだけ副作用のある箇所を
局所的にして、切り離すことが重要
![Page 48: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/48.jpg)
「読みやすく」「副作用の少ない」
関数型の概念を学んでみませんか
(´・ω・)?
![Page 49: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/49.jpg)
ありがとうございました
(´・ω・)っ旦~
![Page 50: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/50.jpg)
参考文献
![Page 51: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/51.jpg)
【おまけ】
![Page 52: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/52.jpg)
そもそも、Rubyは
「綺麗に書くほど速い=最適化される」
言語
![Page 53: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/53.jpg)
Rubyで先ほどのような
for文はまず使わない
確実に「もっと美しい書き方」がある
![Page 54: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/54.jpg)
Rubyを「知る」には
実は関数型の概念がいる
私がRubyのありがたさを実感したのは
「ふつうのHaskell」を読んだ後
![Page 55: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/55.jpg)
実際、関数型として書いたRubyと
元々関数型のScalaのコードは
非常によく似ている
![Page 56: 「再代入なんて、あるわけない」 ~ふつうのプログラマが関数型言語を知るべき理由~ (Gunma.web #5 2011/05/14)](https://reader033.vdocuments.site/reader033/viewer/2022051514/5484fcf2b479590f0d8b4c9b/html5/thumbnails/56.jpg)
コマ大数学科の問題をRubyとScalaで解いてみる
d.hatena.ne.jp/parrot_studio/20110302/1299051431