Yes you can make my little example work by implementing dynamic scope with a stack for saving/restoring binding values. Given R's reflection capabilities and rm() with an envir argument that has its own issues. If you want to try to get this right and maintain it in your own packages that is up to you. I can't see the cost/benefit calculation justifying having it in base.
Best, luke On Mon, 7 Oct 2019, Lionel Henry wrote: > On 7 Oct 2019, at 18:17, Tierney, Luke <luke-tier...@uiowa.edu> wrote: > >> Here is a stylized example: > > The previous value of the binding should only be restored if it > existed: > > g <- function(x, y) { > rlang::scoped_bindings(xx = x, .env = parent.frame()) > y > get("xx") + 10 > } > > # Good > g(1, 2) > #> [1] 11 > > # Still good? > g(1, g(1, 2)) > #> [1] 11 > > >> If you play these games whether you get the result you want, or an >> obvious error, or just the wrong answer depends on argument evaluation >> order and the like. > > I think the surprises are limited because the pattern has stack-like > semantics. We get in a new context where `.` gains a new meaning, and > when we exit the previous meaning is restored. > > One example where this could lead to unexpected behaviour is trying to > capture the value of the placeholder in a closure: > > f <- function(x) { > x %>% { > identity(function() .) > } > } > > # This makes sense: > f("A")() > #> Error: object '.' not found > > # This doesn't: > "B" %>% { f("A")() } > #> [1] "B" > > >> Not to mention that you would be telling users they are not allowed >> to use '.' as a variable name for their own purposes or you would be >> polluting their environment with some other artificial symbol that >> they would see in debugging. > > That's a good point. Debugging allows to move up the call stack before > the context is exited, so you'd see the last value of `.` in examples > of nested pipes like `foo %>% bar( f %>% g() )`. That could be confusing. > > >> Anything going in base needs to worry even about artificial cases. >> Yes, there are things in base that don't meet that standard. No, that >> is not a reason to add more. > > Agreed. What I meant by artificial cases is functions making > questionable assumptions after peeking into foreign contexts etc. > > I'm worried about what happens with important language constructs like > `<-` and `return()` when code is evaluated in a local context. That > said, I think binding pipe values to `.` is more important than these > particular semantics because the placeholder is an obvious binding to > inspect while debug-stepping through a pipeline. So evaluating in a > child is probably preferable to giving up the placeholder altogether. > > Best, > Lionel > -- Luke Tierney Ralph E. Wareham Professor of Mathematical Sciences University of Iowa Phone: 319-335-3386 Department of Statistics and Fax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: luke-tier...@uiowa.edu Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel