Python と Smalltalk (とC++0x) のクロージャー
i = 1 def func() print i i = 5 func()
表示されるのは
5
なぜかというと、関数 func() が参照しているのは、「グローバルスコープの i」という変数であって、その値を変えてから呼んだのだから、func() が評価される時点での i は 5 だという理屈だ。
この動作が果して良いのかどうか、Python の哲学には詳しくないので分からないが、Smalltalk ではどうなんだろうと思い、調べてみた。ソースは以下のとおり:
|i func| i := 1. func := [Transcript showCR: i]. i := 5. func value.
結果は
5
同じか。今になって、Smalltalk at: #i put: 1 も試すべきだったとちょっと後悔。
うーん、実は少し不満…かもしれない。まあ、実際の使用を考えれば、こうでないと困るのが事実なんだろうけど、
i := 5
というのは、Smalltalk では i に束縛されていた 1 というオブジェクトは捨ておいて、新たに 5 というオブジェクトを束縛する…と認識していたから。他の言語だったら気にしないのかもしれないが、Smalltalk となると、どうも変数ベースでものを考えるのが邪道に思えてしまう…。
ところで、C++0x でもクロージャーが登場するらしいが、噂ではこのような文法になるとか:
int i = 1; auto func = <> () export(i) {cout << i << endl;}; i = 5; func();
本当かな? コンパイラがないのでなんとも。結果は 5 のはず。
ちなみに:
- 環境は Smalltalk/X
- スーパーpre記法で Smaltalk が使えるのは、はてな スーパーpre記法 in Smalltalk - みねこあ で知りました。感謝。