R言語: クロージャ

クロージャについて
関数が、その関数のスコープ外のレキシカル変数を参照している状況のことらしい.まあ、包含関係にある一段階上の親(スコープ)の変数を参照してるってことかな.この関数をクロージャといったり、この関数と参照されている変数を含めてクロージャといったりするらしい.


■例1

outer.fun1 <- function(a){
con <- 1
inner.fun <- function(x){
con <- con + 1
con * x + a
}
return(inner.fun)
}

#outer.fun1内の変数conとの違いを調べるために宣言
con <- 10

f1 <- outer.fun1(1) #aに1を与えている

f1(3) #出力は7
f1(3) #出力は7
f1(3) #出力は7

print(con) #出力は10


■例2 カウンターみたいな機能
outer.fun2 <- function(){
con <- 0
inner.fun <- function(){
#永続付値演算子「<<-」を使うところがミソ.
#これは、一つ階層が上のスコープ(親)の変数を書き換えることが可能.
con <<- con + 1
}
return(inner.fun)
}

con <- 10

f2 <- outer.fun2()

f2() #出力は1
f2() #出力は2
f2() #出力は3

print(con) #出力は10


■例3 カウンターみたいな機能(無名関数)
outer.fun3 <- function(){
con <- 0
function(){
con <<- con + 1
}
}

con <- 10

f3 <- outer.fun3()

f3() #出力は1
f3() #出力は2
f3() #出力は3

print(con) #出力は10


クロージャの特徴(例2より)
1) outer.fun2の変数conはinner.fun内で参照されており、スコープ(outer.fun2の書かれた部分)が終了した後でもメモリ上から削除されない.
※あるスコープ内で宣言した変数は、そのスコープが終わったときに、どこからも参照されていないとメモリから削除されるらしい.
2) outer.fun2という関数の範囲(あるスコープ)から外れると、その関数内で宣言した変数conの中身を見ることができなくなる. この関数内のconと外のconは別物である.
3) outer.fun2という関数のスコープを外れると、inner.funからだけouter.fun2内の変数conを使うことができる.


便利そうだが、今のところ使い道が思い浮かばない.

クロージャについての説明は、言語はjavascriptだが、以下のサイトが分かりやすい。
http://dqn.sakusakutto.jp/2009/01/javascript.html