From wdunlap at tibco.com  Sat Jul 29 00:53:44 2017
From: wdunlap at tibco.com (William Dunlap)
Date: Fri, 28 Jul 2017 15:53:44 -0700
Subject: [Rd] force promises inside lapply
In-Reply-To: <a08cf018-5c19-fe67-9ee8-6d0e403b9cfa@gmail.com>
References: <a08cf018-5c19-fe67-9ee8-6d0e403b9cfa@gmail.com>
Message-ID: <CAF8bMcZOh4W-imEt8tnFpH0zzEEx5PjCVKJO-yhF5X+Tvj_j3w@mail.gmail.com>

1: substitute(), when given an argument to a function (which will be a
promise) gives you the unevaluated expression given as the argument:

>  L <- list(a=1, b=2, c=3)
> str(lapply(L, function(x) substitute(x)))
List of 3
 $ a: language X[[i]]
 $ b: language X[[i]]
 $ c: language X[[i]]

The 'X' and 'i' are in a frame constructed by lapply and you are not really
supposed to depend on the precise form of those expressions.

2: An evaluated promise is still a promise: it has the 'evaled' field set
to TRUE and the 'value' field set to the result of evaluating 'code' in
'env'.

> f <- function(x, force) {
     if (force) force(x)
     if (pryr::is_promise(x)) promise_info(x)
     else "not a promise"
 }
> str(f(log(-1), force=FALSE))
List of 4
 $ code  : language log(-1)
 $ env   :<environment: R_GlobalEnv>
 $ evaled: logi FALSE
 $ value : NULL
> str(f(log(-1), force=TRUE))
List of 4
 $ code  : language log(-1)
 $ env   : NULL
 $ evaled: logi TRUE
 $ value : num NaN
Warning message:
In log(-1) : NaNs produced

Can you give a concrete example of what you are try to accomplish?

Bill Dunlap
TIBCO Software
wdunlap tibco.com

On Fri, Jul 28, 2017 at 3:04 PM, Benjamin Tyner <btyner at gmail.com> wrote:

> Hi,
>
> I thought I understood the change to lapply semantics resulting from this,
>
>    https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16093
>
> However, would someone care to explain why this does not work?
>
>    > L <- list(a=1, b=2, c=3)
>    > str(lapply(L, function(x){ y <- substitute(x); force(x); eval(y) }))
>    Error in eval(y) : object 'X' not found
>
> Basically, my primary goal is to achieve the same result as,
>
>    > str(lapply(L, function(x){ eval.parent(substitute(x)) }))
>    List of 3
>     $ a: num 1
>     $ b: num 2
>     $ c: num 3
>
> but without having to resort to eval.parent as that seems to rely on an
> implementation detail of lapply.
>
> My secondary goal is to understand why force(x) does not actually force
> the promise here,
>
>    > str(lapply(L, function(x){ force(x); pryr::is_promise(x) }))
>    List of 3
>     $ a: logi TRUE
>     $ b: logi TRUE
>     $ c: logi TRUE
> ,
> Regards
> Ben
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

	[[alternative HTML version deleted]]



[Rd] force promises inside lapply
William Dunlap