Skip to content

Instantly share code, notes, and snippets.

@yutannihilation
Last active October 7, 2017 05:51
Show Gist options
  • Save yutannihilation/e7dc590fb9fafa0819152a65045a6303 to your computer and use it in GitHub Desktop.
Save yutannihilation/e7dc590fb9fafa0819152a65045a6303 to your computer and use it in GitHub Desktop.
f <- function(return_true = TRUE) {
function(return_true = return_true) {
if (return_true) return(TRUE)
FALSE
}
}
f()
#> function(return_true = return_true) {
#> if (return_true) return(TRUE)
#> FALSE
#> }
#> <environment: 0x0000000017f285c8>
f()()
#> Error in f()(): promise already under evaluation: recursive default argument reference or earlier problems?
@TobCap
Copy link

TobCap commented Sep 26, 2017

私も確信持てませんがきっとこんな感じかと思います。

このエラーの最小再現はこちらで出ます。

x <- 99
(function(x = x) x)() # error
(function(x = x) x)(x) # run

次を実行すると何が起こっているかわかりやすいかもしれません

library(pryr)
(function(x = x) promise_info(x))()  # 1.
(function(x = x) promise_info(x))(x) # 2.

PROMSXPであるxは、1. ではenvがクロージャ実行後の内部の環境、2.ではenvがクロージャ―が呼ばれた環境になります。
すなわち、1.ではxはPROMSXPでその評価式はxで環境はクロージャ内部であり、それを評価して値を取り出そうとすると
PROMSXPであるxを評価しての繰り返し、すなわち循環参照になるのでエラーになるのだと思います。

@yutannihilation
Copy link
Author

ありがとうございます。すみません、コメントに気付いていませんでした。。
ちょっとまだ理解しきれていないのですが、循環参照なのでこういうエラーになるんですね。なるほどー。

変数名が別なら大丈夫なんですね。

f <- function(return_true_default = TRUE) {
  function(return_true = return_true_default) {
    if (return_true) return(TRUE)
    FALSE
  }
}
f()()
#> [1] TRUE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment