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

Lazy futures: Specify how/when globals are resolved? #1

Closed
HenrikBengtsson opened this issue Jun 8, 2015 · 3 comments
Closed

Lazy futures: Specify how/when globals are resolved? #1

HenrikBengtsson opened this issue Jun 8, 2015 · 3 comments

Comments

@HenrikBengtsson
Copy link
Owner

Background / current status

## A global variable
a <- 0
f <- lazy({
  42 * a
})

## Since 'a' is a global variable in _lazy_ future 'f',
## which still hasn't been resolved, any changes to
## 'a' until 'f' is resolved, will affect its value.
a <- 1
v <- value(f)
print(v)
stopifnot(v == 42) 

Proposal

Should there be an option to specify when globals in lazy futures should be resolved, e.g.

a <- 0
f <- lazy({
  42 * a
}, globals="eager")
a <- 1
v <- value(f)
print(v)
stopifnot(v == 0) 

versus (current):

a <- 0
f <- lazy({
  42 * a
}, globals="lazy")
a <- 1
v <- value(f)
print(v)
stopifnot(v == 42) 

The purpose of this would mostly be to (i) illustrate the importance of understanding how globals are handled, and (ii) provide a lazy future mechanism that as far as possible emulated what happens when evaluating futures in external processes/R sessions.

To add this, we also need to add dependency on the globals package.

@HenrikBengtsson
Copy link
Owner Author

Will hold this one of for a while, because if introduced it would also add dependency on globals and that might be too specific for other needs. It's possible that a better strategy is to keep this outside of this package and leave it to the specific "Future" packages downstream.

@HenrikBengtsson
Copy link
Owner Author

Some arguments for having 'future' handle globals too:

Mandelbrot demo

> plan(lazy)
> demo('mandelbrot', package='future')

will calculate convergence counts for the exact same (=the last one) complex plane for all iterations, because the globals are only resolved when evaluated. Globals needs to be "frozen" (exported) for each future.

Fibonacci series

The following example for illustrating futures, does not work with current "lazy" implementation, because all future iterations end up using the same value on iterator variable i (=50) when resolved:

> library("future")
> library("listenv")
> plan(lazy)
> f <- listenv()
> f[[1]] <- 0
> f[[2]] <- 1
> for (i in 3:50) f[[i]] %<=% { f[[i-2]] + f[[i-1]] }
> f[[4]]
Error in get(var, envir = x, inherits = FALSE) :
  promise already under evaluation: recursive default argument reference or earlier problems?

@HenrikBengtsson
Copy link
Owner Author

See commit f65a767. Added lazy(..., globals=TRUE), which is also the default. Updated tests, examples and demos accordingly.

This only provides a mechanism for including ("freezing") globals for lazy future, and eager futures don't need it. If it turns out it is useful to provide an automatic mechanism for this in future(), then it can be added in a future release. If so, then open a new issue on this topic.

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

No branches or pull requests

1 participant