フォースの力に頼らない

ひとりアドベントカレンダー18日目。
Advanced RにもあるようにRは遅延評価を導入しているため、思ってたのんと違うわこれという動作がたまにある。
例えばlapply関数の挙動。

> add <- function(x) {
+     function(y) x + y
+ }
> adders <- lapply(1:10, add)
> adders[[1]](10)
[1] 20 # ここは11になって欲しい。
> adders[[10]](10)
[1] 20

これを防ぐにはforce関数を用いるなどして強制評価する必要があった。

add <- function(x) {
  force(x)
  function(y) x + y
}
adders2 <- lapply(1:10, add)
adders2[[1]](10)
[1] 11
adders2[[10]](10)
[1] 20

ここまではAdvanced Rにもある通りの話。
2年前の仏の記事にもその謎解きが書かれている。
http://d.hatena.ne.jp/teramonagi/20131117/1384694056

しかし実は現在のバージョンのRではこの点が解決されており、force関数を使わずとも期待通りの動きをするようになっている(下記のNEWSの中のPR16093およびバグ報告参照)。
https://cran.r-project.org/doc/manuals/r-release/NEWS.html
https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=16093

ここAdvanced Rを盲信すると混乱するから注意。
web版のAdvanced Rは新しい方のバージョンのRで動かしているのでコード実行例ではバグが直っているにもかかわらず、本文の記述は昔のバージョンで動かしたときのままなので、例と噛み合わず変なことになっている。
ということで、そんな食い違いも訳注で対応してる翻訳版が来月に出ますよ!期待ですね!

R言語徹底解説

R言語徹底解説