1% File src/library/base/man/delayedAssign.Rd
2% Part of the R package, https://www.R-project.org
3% Copyright 1995-2015 R Core Team
4% Distributed under GPL 2 or later
5
6\name{delayedAssign}
7\alias{delayedAssign}
8\alias{promise}
9\alias{promises}
10\title{Delay Evaluation}
11\description{
12  \code{delayedAssign} creates a \emph{promise} to evaluate the given
13  expression if its value is requested.  This provides direct access
14  to the \emph{lazy evaluation} mechanism used by \R for the evaluation
15  of (interpreted) functions.
16}
17\usage{
18delayedAssign(x, value, eval.env = parent.frame(1),
19              assign.env = parent.frame(1))
20}
21\arguments{
22  \item{x}{a variable name (given as a quoted string in the function call)}
23  \item{value}{an expression to be assigned to \code{x}}
24  \item{eval.env}{an environment in which to evaluate \code{value}}
25  \item{assign.env}{an environment in which to assign \code{x}}
26}
27\value{
28  This function is invoked for its side effect, which is assigning
29  a promise to evaluate \code{value} to the variable \code{x}.
30}
31\details{
32  Both \code{eval.env} and \code{assign.env} default to the currently active
33  environment.
34
35  The expression assigned to a promise by \code{delayedAssign} will
36  not be evaluated until it is eventually \sQuote{forced}.  This happens when
37  the variable is first accessed.
38
39  When the promise is eventually forced, it is evaluated within the
40  environment specified by \code{eval.env} (whose contents may have changed in
41  the meantime).  After that, the value is fixed and the expression will
42  not be evaluated again.
43}
44\seealso{
45  \code{\link{substitute}}, to see the expression associated with a
46  promise, if \code{assign.env} is not the \code{\link{.GlobalEnv}}.
47}
48\examples{
49msg <- "old"
50delayedAssign("x", msg)
51substitute(x) # shows only 'x', as it is in the global env.
52msg <- "new!"
53x # new!
54
55delayedAssign("x", {
56    for(i in 1:3)
57        cat("yippee!\n")
58    10
59})
60
61x^2 #- yippee
62x^2 #- simple number
63
64ne <- new.env()
65delayedAssign("x", pi + 2, assign.env = ne)
66## See the promise {without "forcing" (i.e. evaluating) it}:
67substitute(x, ne) #  'pi + 2'
68\dontshow{stopifnot(identical(substitute(x,ne), quote(pi + 2)))}
69
70### Promises in an environment [for advanced users]:  ---------------------
71
72e <- (function(x, y = 1, z) environment())(cos, "y", {cat(" HO!\n"); pi+2})
73## How can we look at all promises in an env (w/o forcing them)?
74gete <- function(e_)
75   lapply(lapply(ls(e_), as.name),
76          function(n) eval(substitute(substitute(X, e_), list(X=n))))
77
78(exps <- gete(e))
79sapply(exps, typeof)
80
81(le <- as.list(e)) # evaluates ("force"s) the promises
82stopifnot(identical(unname(le), lapply(exps, eval))) # and another "Ho!"
83}
84\keyword{programming}
85\keyword{data}
86