[Rd] Lazy-evaluate elements wrapped with invisible

Bill Dunlap w||||@mwdun|@p @end|ng |rom gm@||@com
Sat Oct 29 17:54:48 CEST 2022


>  the `delayed` object is ready to be garbage collected if not assigned
immediately.
I am not sure what is meant here.  Any object (at the R code level) is
ready to be garbage collected if not given a name or is not part of an
object with a name.  Do you mean a 'delayed' component of a list
should be considered
garbage if not 'immediately' extracted from a list?   Could you show a few
usage cases?

-Bill

On Fri, Oct 28, 2022 at 7:41 PM Dipterix Wang <dipterix.wang using gmail.com>
wrote:

>
> This is not quite true. The value, even when invisible, is captured by
> .Last.value, and
>
> > f <- function() invisible(5)
> > f()
> > .Last.value
> [1] 5
>
>
> I understand .Last.value will capture the function returns, but that only
> happens in the top-level... I guess?
>
> In the followings code, I think .Last.value does not capture the results
> of f, h, k, l
>
> g <- function() {
>   f(); h(); k(); l()
>   return()
> }
> g()
>
>
> Maybe I caused confusion by mentioning `invisible` function. I guess it
> should be a new function (let’s call it `delayed`). The function does not
> have to be limited to “printing”. For example, a digest key
>
>
> a <- function(key, value) {
>   map$set(key, value)
>
>   return(*delayed*({
>     digest(value)
>   }))
> }
>
> Or an async evaluation of which the saved result might not be needed if
> not assigned (detached), or the result will be “joined” to the main process
>
> a <- function(path) {
>   # async
>   f <- future::future({
>     # calculate, and then write to path
>     saveRDS(…, path)
>   })
>
>   return(*delayed*({
>     resolve(f) # wait till f to finish
>
>     readRDS(path)
>   }))
> }
>
> Although I could use wrappers such as formula, quosure, or environment to
> achieve similar results, there are two major differences
>
> 1. There is an extra call to get the lazy-evaluated results (if I do want
> to resolve it)
> 2. The returned objects have to contain sort of “environment” component in
> it. It can’t just be simple objects like vectors, matrices, lists, …
> (also you can't immediately garbage collect the enclosing environment)
>
> From the implementation perspective, the `delayed` object is ready to be
> garbage collected if not assigned immediately.
>
> Best,
> - D
>
>
> This is not quite true. The value, even when invisible, is captured by
> .Last.value, and
>
> > f <- function() invisible(5)
> > f()
> > .Last.value
> [1] 5
>
> Now that doesn't actually preclude what you're suggesting (just have to
> wait for .Last.value to be populated by something else), but it does
> complicate it to the extent that I'm not sure the benefit we'd get would be
> worth it.
>
> Also, in the case you're describing, you'd be pushing the computational
> cost into printing, which, imo, is not where it should live. Printing a
> values generally speaking, should just print things, imo.
>
> That said, if you really wanted to do this, you could approach the
> behavior you want, I believe (but again, I think this is a bad idea) by
> returning a custom class that wraps formula (or, I imagine, tidyverse style
> quosures) that reach back into the call frame you return them from, and
> evaluating them only on demand.
>
> Best,
> ~G
>
>
>> This idea is somewhere between `delayedAssign` and eager evaluation.
>> Maybe we could call it delayedInvisible()?
>>
>> Best,
>> - Zhengjia
>>
>> ______________________________________________
>> R-devel using r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
>

	[[alternative HTML version deleted]]



More information about the R-devel mailing list