遅延コワい

Schemeを使うとき、しばしば以下のようにクロージャのなかに関数を閉じ込める。
例えばメモ化した関数を作りたいときや、呼び出し回数をカウントできる関数を作りたいときとかにそうする。

(define (a f) (lambda () (f)))
(define (x) 0)
(define x (a x))
(x) ;;;=> 0

Rでも同じように書いてみた所、Errorが出た。どうやら引数が遅延評価されているのが原因のようだ。

a <- function(f){ function(){ f() } }
x <- function(){ 0 }
x <- a(x)
x() ###=> エラー:  評価があまりに深く入れ子になっています。無限の再帰か

このようにfを閉じ込める前に強制的に評価してあげれば大丈夫だった。

a <- function(f){ force(f); function(){ f() } }
x <- function(){ 0 }
x <- a(x)
x() ###=> 0