> 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@r-project.org <mailto:R-devel@r-project.org> mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel 
> <https://stat.ethz.ch/mailman/listinfo/r-devel>


        [[alternative HTML version deleted]]

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to