Successfully reported this slideshow.                         Upcoming SlideShare
×

# 関数型都市忘年会『はじめての函数型プログラミング』

http://atnd.org/events/21895

• Full Name
Comment goes here.

Are you sure you want to Yes No ### 関数型都市忘年会『はじめての函数型プログラミング』

1. 1. はじめての函数型プログラミング うさみけんた Zonu.EXE 2011年12月10日 関数型都市勉強会
2. 2. あんた誰よò  うさみけんたò  技術趣味者 ò  プログラミング言語 ò  ガジェット… etc.ò  Rubyistです(∑ÿØ ò  お仕事では、いろいろ。
3. 3. はじめにò  函数ってなあに？ からはじめますò  基本的には函数型プログラミングを知らない、 よくわからないひと向けな感じでò  函数型プログラミング言語じゃなくても 利点を巧く取り入れてプログラミングできるよ！ò  発表者は初心者です！！１ ←重要
4. 4. 函数とは何かf (x) = 3x + 2 こんなの
5. 5. わたしたちは算数で習ったò  f (x) = 3x + 2 x -2 -1 0 1 2 y = 3x + 2 y -4 -1 2 5 8ò  この例は一次方程式の函数 ò  ある数 x に対して、対応する値 y を計算して返す ò  y = 3! ("2) + 2 y = 3! (1) + 2 = 5 = "6 + 2 = "4ò  ほかにも三角函数とか対数函数とか高校(数学IIとか) でやった気がしますね
6. 6. 函数とは何かò  英語では function (ファンクション)ò  函数(かんすう) = 関数 ò  漢字表記についてはいろんな経緯があるけど省略 ò  どうして上海をシャンハイと読むのか？ ò  (少くとも日本人には)どっちでもいいò  このセッションに限っては「函数」で統一します
7. 7. プログラムでは…ò  f (x) = 3x + 2ò  C言語なら、だいたいこんな感じに書けますね… int f(int x){ printf(“%d, ”, f(0)); return 3 * x + 2; printf(“%d, ”, f(1)); } printf(“%d ”, f(2)); 2, 5, 8 for(int n = -2; n <= 3; n++){ n=-2 f(n)=-4 printf(“n=%2d f(n)=%2dn”, n, f(n)); n=-1 f(n)=-1 } n= 0 f(n)= 2 ………
8. 8. ちょっと考えてみる#include <stdio.h>int main(void){ for(int n = -2; n <= 3; n++){ printf(“n=%2d f(n)=%2dn”, n, f(n)); } return 0;}ò  このプログラムの問題点 ò  ぶっちゃけ、継続条件を考えるのめんどくないです? ò  うっかり n < 3 とか n >= 3 とか書いちゃったら…?
9. 9. Pythonならどうするよfor n in range(-2, 3): print “n=%2d f(n)=%2d” % (n, f(n))ò  range(-2, 3) = [-2, -1, 0, 1, 2] というリスト ò  range(a, b) は「a 以上 b 未満」 と読めるò  n の値は -2, -1, 0, 1 2 と変化するò  コードのメリット ò  継続条件が「ない」 ò  リストの各要素に対して処理を実行
10. 10. 設計指向の違いò  キミの言語は何指向？ ò  C言語は手続き型プログラミング言語 ò  Pythonは手続き型+オブジェクト指向+函数型 ò  F#/Scalaは函数型+オブジェクト指向+手続き型 ò  Haskellは純粋函数型プログラミング言語ò  補足 ò  どの言語でその記述ができるか、という話ではない ò  例: C言語でもオブジェクト指向プログラミングは可能
11. 11. 設計指向の違い ò  手続き型 ò  オブジェクト指向 ò  函数型ò  処理の抽象化の違い=人間がどのように考えるかò  「大雑把に言って」コンパイラが最適化できるので これらの間で実行の速度差は出にくくなっている ò  むしろ、メモリの型付けシステムによって差がつく ò  CやC++、F#などは静的型付けの仲間 = 速い
12. 12. 改めて、函数型言語ò  一般的には、ラムダ計算の概念を論理的基盤にした プログラミング言語のことを指すò  函数型言語では函数をお手軽に扱える ò  プログラム中で簡単に函数を定義したり、 変数に代入できたり、使い捨ての函数を作ったり！ò  抽象度の高いループ ò  リストに対する処理 ò  再帰処理
13. 13. 函数型言語の系統ò  LISP (LISt Processing) ò  Scheme ò  Common Lisp ò  Emacs Lispò  ML (Meta-Language) ò  Standard ML (SML) ò  OCaml, F# ò  (Haskell) (Scala)
14. 14. R.I.P.
15. 15. 手続き型の中の函数型ò  函数型言語で培われた要素は、部分的に 手続き型言語にも持ち込まれているò  例えば: Ruby、Python、JavaScriptなどは ò  簡単に配列(リスト)を使って反復処理ができる ò  プログラム中で簡単に函数(相当)を定義して使える
16. 16. JavaScriptだと…// function文で定義する場合function f1(x){ return 3 * x + 2;}// function式に代入する場合var f2 = function(x){ return 3 * x + 2 }// 作成した函数をそのままで使用する場合console.log( function(x){ return 3 * x + 2 }(5) )// 配列をその場で作って、それぞれにf1を適用[-2,-1,0,1,2].map(f1)//=> [-4, -1, 2, 5, 8]// その場で作った配列にその場で作った函数をry[-2,-1,0,1,2].map(function(x){return 3 * x + 2 })
17. 17. Rubyだと# lambdaメソッドでf1 = lambda{|x| return 3 * x + 2;}f1 #=> 17# lambdaを配列のそれぞれに適用[-2,-1,0,1,2].map{|x| return f1[x] }#=> [-4, -1, 2, 5, 8]# lambdaを配列のそれぞれに適用[-2,-1,0,1,2].map{|x| return 3 * x + 2;}#=> [-4, -1, 2, 5, 8]
18. 18. Pythonなら…再び# 順番に実行されるだけなのでMapではないdef f1(x): return 3 * x + 2for n in range(-2, 3): print f(n)# リスト内包 = map と同じ[f1(n) for n in range(-2, 3)]#=> [-4, -1, 2, 5, 8]# リスト内包: for 内で関数を作れる[ (lambda x: 3*x+2)(n) for n in range(-2, 3)]#=> [-4, -1, 2, 5, 8]
19. 19. ラムダ計算とは何かò  ラムダ計算（lambda calculus）は、理論計算機科学や 数理論理学における、関数の定義と実行を抽象化した 計算体系である。ラムダ算法とも言う。ò  例えば、ある数に 2 を加える関数 f を考える。これは 通常の書き方では f(x) = x + 2 と書くことができるだ ろう。この関数 f は、ラムダ計算の式（ラムダ式とい う）では λx. x + 2 と書かれる。……この関数に 3 を 適用した結果の数 f(3) は (λx. x + 2) 3 と書かれる。 ò  以上、Wikipediaより引用 (ja.Wp: ラムダ計算)
20. 20. Pythonならラムダ計算もò  RubyでもJavaScriptでもできるんですけどねò  Pythonでラムダ計算 - DT戦記(zonu_exeの日記) ò  この内容を実演しました ò  別にPythonはラムダが得意なわけではないです
21. 21. 発表ここまでò  以下のスライドは後からの補足。
22. 22. 質疑応答ò  好きな函数型言語は？ ò  F#です(∑ÿØ ò  最近は「ふつうのHaskellプログラミング」を読んでる ò  でもまづはF#ですよね
23. 23. 質疑応答ò  Pythonのmapを避けたのはなぜか？ ò  Pythonの作者がLisp的なmapとかlambdaを入れるのが 嫌だったらしいので避けました ò  Pythonでは函数内にローカル変数を作れるので、 ちょっと面倒でもdefで名前付きの函数を作るのが正統 ò  その観点では「Pythonでラムダ計算」は邪道！
24. 24. 質疑応答ò  Pythonでは再帰でスタックを食い潰さないか ò  すみません、調べてませんでした ò  末尾最適化はしてくれないらしいです ò  多くの函数型言語では末尾最適化してくれて、 機械語レベルではループに置換されます
25. 25. あとから気付いたò  手続き型って何よ、ってことをしっかり説明できて ないよねò  説明なしに「(値)に函数を適用」って喋ってたよねò  C++11にはlambdaあるよね、も盛り込んでおけば おいしかったかもしれないò  C++のラムダとデリゲートの話も(ry