クロージャ

JavaScriptの勉強をしているのですが、今読んでいた本に出てきたクロージャを他の言語でも実装してみました。

ちなみに、全て結果は以下となります。

2
101
3
102
function closure(init){
    var counter = init;
    return function(){ return ++counter; };
}

var myClosure1 = closure(1);
var myClosure2 = closure(100);
document.writeln(myClosure1());
document.writeln(myClosure2());
document.writeln(myClosure1());
document.writeln(myClosure2());
def closure(init)
  counter = init
  return lambda { counter += 1 }
end

my_closure1 = closure(1)
my_closure2 = closure(100)
puts my_closure1.call
puts my_closure2.call
puts my_closure1.call
puts my_closure2.call
static Func<int> Closure(int init)
{
    int counter = init;
    return delegate() { return ++counter; };
}

static void Main(string[] args)
{
    Func<int> myClosure1 = Closure(1);
    Func<int> myClosure2 = Closure(100);
    Console.WriteLine(myClosure1());
    Console.WriteLine(myClosure2());
    Console.WriteLine(myClosure1());
    Console.WriteLine(myClosure2());
}

今読んでいた本によると、JavaScriptではスコープチェーンという仕組みによって、匿名関数内で使われるローカル変数の寿命が伸ばされているとのこと。
Rubyでは、ブロックが生成されたときのbindingをProcオブジェクトが保持することによってクロージャを実現していると、昔どこかで読んだことがあります。ちなみに、Proc#bindingでProcオブジェクトの保持しているbindingを取得できるようですね。
C#はどういう仕組なのかなぁ? C#は、猫でもわかる本を読んだだけだからこういう深いところはいまいち分かりません。

ちなみに私はRuby大好きなのですが、JavaScriptの関数オブジェクトには憧れますね。Procとかdelegateとか別概念を用意しなくてもクロージャを実現できているところがかっこいいです。

JavaScriptマスターブック

JavaScriptマスターブック