Weitere ähnliche Inhalte Ähnlich wie 関数型都市忘年会『はじめての函数型プログラミング』 (20) Mehr von Kenta USAMI (20) 関数型都市忘年会『はじめての函数型プログラミング』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. 函数とは何か
ò 英語では function (ファンクション)
ò 函数(かんすう) = 関数
ò 漢字表記についてはいろんな経緯があるけど省略
ò どうして上海をシャンハイと読むのか?
ò (少くとも日本人には)どっちでもいい
ò このセッションに限っては「函数」で統一します
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
………
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. 設計指向の違い
ò キミの言語は何指向?
ò C言語は手続き型プログラミング言語
ò Pythonは手続き型+オブジェクト指向+函数型
ò F#/Scalaは函数型+オブジェクト指向+手続き型
ò Haskellは純粋函数型プログラミング言語
ò 補足
ò どの言語でその記述ができるか、という話ではない
ò 例: C言語でもオブジェクト指向プログラミングは可能
11. 設計指向の違い
ò 手続き型
ò オブジェクト指向
ò 函数型
ò 処理の抽象化の違い=人間がどのように考えるか
ò 「大雑把に言って」コンパイラが最適化できるので
これらの間で実行の速度差は出にくくなっている
ò むしろ、メモリの型付けシステムによって差がつく
ò CやC++、F#などは静的型付けの仲間 = 速い
13. 函数型言語の系統
ò LISP (LISt Processing)
ò Scheme
ò Common Lisp
ò Emacs Lisp
ò ML (Meta-Language)
ò Standard ML (SML)
ò OCaml, F#
ò (Haskell) (Scala)
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. Rubyだと
# lambdaメソッドで
f1 = lambda{|x|
return 3 * x + 2;
}
f1[5]
#=> 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. Pythonなら…再び
# 順番に実行されるだけなのでMapではない
def f1(x):
return 3 * x + 2
for 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. ラムダ計算とは何か
ò ラムダ計算(lambda calculus)は、理論計算機科学や
数理論理学における、関数の定義と実行を抽象化した
計算体系である。ラムダ算法とも言う。
ò 例えば、ある数に 2 を加える関数 f を考える。これは
通常の書き方では f(x) = x + 2 と書くことができるだ
ろう。この関数 f は、ラムダ計算の式(ラムダ式とい
う)では λx. x + 2 と書かれる。……この関数に 3 を
適用した結果の数 f(3) は (λx. x + 2) 3 と書かれる。
ò 以上、Wikipediaより引用 (ja.Wp: ラムダ計算)
23. 質疑応答
ò Pythonのmapを避けたのはなぜか?
ò Pythonの作者がLisp的なmapとかlambdaを入れるのが
嫌だったらしいので避けました
ò Pythonでは函数内にローカル変数を作れるので、
ちょっと面倒でもdefで名前付きの函数を作るのが正統
ò その観点では「Pythonでラムダ計算」は邪道!