このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

groovyとラムダ式(4):自由変数の束縛

λx.(x + a) のようなラムダ式で、xは仮引数(ラムダ式の束縛変数といいます)ですが、定義本体内に仮引数リストにない変数aが出てきますよね。aみたいな、仮引数宣言されてない変数を自由変数と呼びます。

自由変数が、いつどのように束縛(具体化)されるかは、けっこう重要な問題です。で、調べてみる。


// 自由変数の束縛タイミング
a = 3
X = {|x| x + a}
a = 8
println X(2) // 5か10か?


10

実行時に束縛されてる。ウーン、これはどうかなぁ。インタプリタでは、まー、普通の動作なのですが、実行時の環境によってクロージャの挙動が変わってしまいます。それを利用するテクニックもあるでしょうけど、分かりにくくてハマると思いますよ。

束縛が実行時(評価時)に起きるなら、定義時の環境(自由変数の束縛状況/値)はどうでもいいはずです。なのに…


// 自由変数の束縛タイミング
// aの値は未定義
X = {|x| x + a}
a = 8
println X(2)


Caught: java.lang.NullPointerException
at lambda2.run(C:\Documents and Settings\Hiyama\tmp\lambda2.groovy)
at lambda2.main(C:\Documents and Settings\Hiyama\tmp\lambda2.groovy)

なんで例外を出すのですか、君は>groovy

それはともかく、こんなこともできるわけですが:


// クロージャ内から環境の変数を変更する
a = 3
X = { a = 10 }

println a
X()
println a


3
10

できるからって、むやみに使うもんじゃないね。

(続く、けど明日かな)