[Rd] [External] Re: should base R have a piping operator ?

Tierney, Luke |uke-t|erney @end|ng |rom u|ow@@edu
Mon Oct 7 21:41:30 CEST 2019


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-tierney using 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-tierney using uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu



More information about the R-devel mailing list