-
Notifications
You must be signed in to change notification settings - Fork 19
Description
I have this issue in furrr as well, but wanted to start discussion here so we can both do the same thing.
In the following example, I understand why wrapper2() always finds y, but I would imagine that wrapper("y") should also find y. This is something that I've hit while writing tests for furrr.
I think the issue is that the environment used to find these globals is just the execution environment of future_lapply(). It is created here:
https://github.com/HenrikBengtsson/future.apply/blob/1d19bbf4ab6efe37dd048343d6644cc33dccf8ef/R/future_lapply.R#L159
And passed through and eventually used here:
https://github.com/HenrikBengtsson/future.apply/blob/1d19bbf4ab6efe37dd048343d6644cc33dccf8ef/R/globals.R#L33
The parent environment of this env is the future.apply namespace environment, so there is no way for it to find y. I'm wondering if instead we should be calling envir <- parent.frame() from future_lapply() and friends to find globals. That would contain y, and I think it would have a correct chain of environments for finding other globals further up. Thoughts?
library(future.apply)
#> Loading required package: future
plan(multisession, workers = 2)
fn <- function(x) {
exists("y")
}
wrapper <- function(future.globals = TRUE) {
y <- 1
future_lapply(1, fn, future.globals = future.globals)
}
wrapper2 <- function(future.globals = TRUE) {
y <- 1
# finds `y` from enclosing env of `fn`
fn <- function(x) {
exists("y")
}
future_lapply(1, fn, future.globals = future.globals)
}
wrapper()
#> [[1]]
#> [1] FALSE
wrapper("y")
#> [[1]]
#> [1] FALSE
wrapper2()
#> [[1]]
#> [1] TRUE
wrapper2("y")
#> [[1]]
#> [1] TRUECreated on 2020-07-29 by the reprex package (v0.3.0)