> 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
>
> ______________________________________________
> [email protected] <mailto:[email protected]> mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> <https://stat.ethz.ch/mailman/listinfo/r-devel>
[[alternative HTML version deleted]]
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel