俺が思ってたんと違う挙動の遅延評価
ある程度コードを抽象化しようと言う時に「関数を返す関数」を使うのは良いアイディアだと思うのですが、以下のように書くとハマれるってのでメモ。
ここでは「異なるパラメーター(1〜3)を持つ3つの関数を生成し、それぞれに対して実際の計算を行うものの…期待する結果とはずれる」という話です。
コードはこんな感じ。
#関数返す関数 make.hoge <- function(m){function(x)x*m} #1*x, 2*x, 3*xとなるような関数リストを返してる(つもり) hoges <- sapply(1:3, make.hoge) #1を期待 hoges[[1]](1) #2を期待 hoges[[2]](1) #3を期待 hoges[[3]](1)
これを直すにはただ1行、「変数mを強制的に評価する」ようなコードをmake.hoge関数の中に追加すれば良い。これでちゃんと直る!
#関数返す関数 make.hoge <- function(m) { #mを強制的に評価!!!!! m function(x)x*m } #1*x, 2*x, 3*xとなるような関数リストを返してる(つもり) hoges <- sapply(1:3, make.hoge) #1を期待 hoges[[1]](1) #2を期待 hoges[[2]](1) #3を期待 hoges[[3]](1)
なんでこんなことになるのかって話は以下の@tyatsuta氏の資料で完璧に説明されています。ありがとうございます!