Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Objects of class "expression" don't seem to be searched recursively #77

Open
DavisVaughan opened this issue Oct 25, 2021 · 3 comments
Open
Assignees

Comments

@DavisVaughan
Copy link
Contributor

It seems like x should be identified as a potential global here:

expressions <- parse(text = "x")
expressions
#> expression(x)

# Why isn't `x` found?
globals::findGlobals(expressions)
#> character(0)

# We can find it like this:
expressions[[1]]
#> x
globals::findGlobals(expressions[[1]])
#> [1] "x"

# Or like this
list_of_expressions <- list(quote(x))
list_of_expressions
#> [[1]]
#> x

globals::findGlobals(list_of_expressions)
#> [1] "x"

Originally reported in DavisVaughan/furrr#209

@DavisVaughan
Copy link
Contributor Author

DavisVaughan commented Oct 25, 2021

It is worth noting that future_map() fails, but future_lapply() works. That only works because of the fact that future_lapply() converts the input to a list with as.list() before the globals are searched - which gives us something like list_of_expressions above that findGlobals() can search correctly.

I still think the problem is that findGlobals() can't search "expression" types recursively

library(future.apply)
#> Loading required package: future
library(furrr)
plan(multisession, workers = 2)

x <- 0

y <- parse(text = "x")
y
#> expression(x)

future_map(y, eval)
#> Error in ...furrr_fn(...): object 'x' not found

future_lapply(y, eval)
#> [[1]]
#> [1] 0

# Because future_lapply() does this ahead of time:
# if (!is.vector(X) || is.object(X)) 
#   X <- as.list(X)

# Which gives us the list form that findGlobals() correctly searches:
as.list(y)
#> [[1]]
#> x

Created on 2021-10-25 by the reprex package (v2.0.1)

@abdellah19jan
Copy link

Hello,

Thank you very much for your reply!

Unfortunately the solution you suggested does not work in my case.

I've tried to formulate a simplified example of the code I am running. It looks like this:

library(furrr)
library(tidyverse)

plan(multisession, workers = 2)

fun <- function(arg) arg + 1
dic <- c("mod" = "fun")

f <- function(x) invoke_map(dic[[x]], 2)

map("mod", f)
future_map("mod", f)

Here are the solutions you suggested (see code below):

1 - Pass the function object as an argument rather than its name as a string: Same result, it works with map but not with future_map.
2 - Use future_lapply instead of future_map: it gives the same error as future_map.

library(future.apply)

f <- function(x) invoke_map(eval(parse(text = dic[[x]])), 2)

map("mod", f)
future_map("mod", f)
future_lapply("mod", f)

The original code I am running is much more complicated than the example above, but I believe if there is a solution that makes the example work, then it will work also for my code.

@HenrikBengtsson HenrikBengtsson self-assigned this Oct 27, 2021
@abdellah19jan
Copy link

Hello,

Is there a solution in the meantime to work around this problem ?

Thanks a lot for your help !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants