いろんな言語のラムダ式とキャプチャ
javaの無名関数がdisられているらしいので他の言語と比較してみた。
http://www.infoq.com/jp/news/2010/06/lambda-syntax-debate
引数に整数型を取り + 1 して返す無名関数を定義してみる。
目的は 72 という数字を 変数 i に格納すること。
なるだけ省略表記を使わないで作るよ。
間違っていたらごめんね!!
いろいろ間違っていたので結構直しました!!
java
・無名ではない関数の場合
int f(int x) { return x + 1; }
・定義してから呼ぶ
#int(int) f = #(int x)(return x + 1); int i = f.(71); //f「.」(71) となっているところが特徴的
・↑を省略化して書く
#int(int) f = #(x)(x + 1); int i = f.(71);
・定義と同時に直接呼ぶ
int i = #(int x)(return x + 1).(71);
・おまけ:キャプチャ
、、、どうやるんだろう。
多分こんな感じすか?
int cap = 1; int cap2 = cap; #int(int) f = #(int x)(return x + 1 + cap2); cap = -100; //ぶっ壊す int i = f.(70);
参考:
http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt
注意:
動く実装がないから間違っているかも知れぬ。
C++0x
・無名ではない関数の場合
int f(int x) { return x + 1; }
・定義してから呼ぶ
std::function<int (int)> f = [](int x) -> int { return x + 1; }; int i = f(71); //iの値は 72
・↑を省略化して書く
auto f = [](int x) -> int { return x + 1; }; int i = f(71); //iの値は 72
・定義と同時に直接呼ぶ
int i = ([](int x) -> int { return x + 1; })(71); //iの値は 72
・おまけ:キャプチャ
int cap = 1; auto f = [cap](int x) -> int { return x + 1 + cap; }; cap = -100; //ぶっ壊す int i = f(70); //だけど保持される //iの値は 72
参考
http://ja.wikipedia.org/wiki/C%2B%2B0x#.E3.83.A9.E3.83.A0.E3.83.80.E9.96.A2.E6.95.B0.E3.81.A8.E3.83.A9.E3.83.A0.E3.83.80.E5.BC.8F
http://codezine.jp/article/detail/4035
C# (3.0以上)
・無名ではない関数の場合
int f(int x) { return x + 1; }
・定義してから呼ぶ
Func<int, int> f = x => { return x + 1; }; int i = f(71); //iの値は 72
・↑を省略化して書く
Func<int, int> f = x => x + 1; int i = f(71); //iの値は 72
・定義と同時に直接呼ぶ
int i = ((Func<int, int>)(x => { return x + 1; }))(71); //iの値は 72
・おまけ:キャプチャ
、、、、どうやるんだろう?
//これでは無理でした。 int cap = 1; Func<int, int> f = x => { return x + 1 + cap; }; cap = -100; //ぶっ壊す int i = f(70); // 70 + 1 + 1 ではなく、 70 + 1 + (-100) で -29 になってしまう //iの値は -29
これらは参照で渡されるので事前に別名に保存すればOKらしい。
int cap = 1; int cap2 = cap; Func<int, int> f = x => { return x + 1 + cap2; }; cap = -100; //ぶっ壊す int i = f(70); //iの値は 72
PHP (5.3以上)
・無名ではない関数の場合
function f($x) { return $x + 1; }
・定義してから呼ぶ
$f = function($x) { return $x + 1; }; $i = $f(71); //iの値は 72
・定義と同時に直接呼ぶ
、、、、どうやるんだろう?
//これはエラーになる。 $i = (function($x){ return $x + 1; })(71);
・おまけ:キャプチャ
$cap = 1; $f = function($x) use($cap) { return $x + 1 + $cap; }; $cap = -100; //ぶっ壊す $i = $f(70); //だけど保持される //$iの値は 72
javascript
無名ではない関数の場合
function f(var x) { return x + 1; }
・定義してから呼ぶ
var f = function(x) { return x + 1; } var i = f(71); //iの値は 72
・定義と同時に直接呼ぶ
var i = (function(var x){ return x + 1; })(71); //iの値は 72
・おまけ:キャプチャ
、、、、どうやるんだろう?
//これではキャプチャできない。。。 var cap = 1; var f = function(x) { return x + 1 + cap; } cap = -100; //ぶっ壊す var i = f(70); // 70 + 1 + 1 ではなく、 70 + 1 + (-100) で -29 になってしまう //iの値は -29
コレも同じく別名に保存しておく。
var cap = 1; let cap2 = cap; var f = function(x) { return x + 1 + cap2; } cap = -100; //ぶっ壊す var i = f(70); //iの値は 72
テスト環境: SpiderMonkey 1.8.0
まとめ
//java #int(int) f = #(int x)(return x + 1); int i = f.(71); //f「.」(71) となっているところが特徴的 //C++0x auto f = [](int x) -> int { return x + 1; }; int i = f(71); //C# Func<int, int> f = x => x + 1; int i = f(71); //PHP $f = function($x) { return $x + 1; }; $i = $f(71); //javascript var f = function(x) { return x + 1; } var i = f(71);
どーでもいいけど、無名関数って、無名剣無明剣(ロマサガの最強の大剣技)と名前がかぶっていてかっこいいよね!!