From murdoch@dunc@n @end|ng |rom gm@||@com  Sat Dec  5 02:01:53 2020
From: murdoch@dunc@n @end|ng |rom gm@||@com (Duncan Murdoch)
Date: Fri, 4 Dec 2020 20:01:53 -0500
Subject: [Rd] New pipe operator
In-Reply-To: <CADfFDC7bT58_+52uvmpHuMMQRNbbmqV3_7t_fc4sgJ_Esw=xag@mail.gmail.com>
References: <e55c2093-0bb5-5f9b-5521-0ca8bdf35953@gmail.com>
 <CALyqOb8c1hHOSaMV+fqXTwpeOsP--KJ_t-oeqMYYafVXeNpqZg@mail.gmail.com>
 <7586e034-e287-0970-6480-f82d747b5445@gmail.com>
 <CADfFDC7bT58_+52uvmpHuMMQRNbbmqV3_7t_fc4sgJ_Esw=xag@mail.gmail.com>
Message-ID: <8c623961-f502-6916-bc8f-eb0c164e1b42@gmail.com>

On 04/12/2020 12:06 p.m., Deepayan Sarkar wrote:
> On Fri, Dec 4, 2020 at 7:35 PM Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
>>
>> On 04/12/2020 8:13 a.m., Hiroaki Yutani wrote:
>>>>    Error: function '::' not supported in RHS call of a pipe
>>>
>>> To me, this error looks much more friendly than magrittr's error.
>>> Some of them got too used to specify functions without (). This
>>> is OK until they use `::`, but when they need to use it, it takes
>>> hours to figure out why
>>>
>>> mtcars %>% base::head
>>> #> Error in .::base : unused argument (head)
>>>
>>> won't work but
>>>
>>> mtcars %>% head
>>>
>>> works. I think this is a too harsh lesson for ordinary R users to
>>> learn `::` is a function. I've been wanting for magrittr to drop the
>>> support for a function name without () to avoid this confusion,
>>> so I would very much welcome the new pipe operator's behavior.
>>> Thank you all the developers who implemented this!
>>
>> I agree, it's an improvement on the corresponding magrittr error.
>>
>> I think the semantics of not evaluating the RHS, but treating the pipe
>> as purely syntactical is a good decision.
>>
>> I'm not sure I like the recommended way to pipe into a particular argument:
>>
>>     mtcars |> subset(cyl == 4) |> \(d) lm(mpg ~ disp, data = d)
>>
>> or
>>
>>     mtcars |> subset(cyl == 4) |> function(d) lm(mpg ~ disp, data = d)
>>
>> both of which are equivalent to
>>
>>     mtcars |> subset(cyl == 4) |> (function(d) lm(mpg ~ disp, data = d))()
>>
>> It's tempting to suggest it should allow something like
>>
>>     mtcars |> subset(cyl == 4) |> lm(mpg ~ disp, data = .)
> 
> Which is really not that far off from
> 
> mtcars |> subset(cyl == 4) |> \(.) lm(mpg ~ disp, data = .)
> 
> once you get used to it.
> 
> One consequence of the implementation is that it's not clear how
> multiple occurrences of the placeholder would be interpreted. With
> magrittr,
> 
> sort(runif(10)) %>% ecdf(.)(.)
> ## [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
> 
> This is probably what you would expect, if you expect it to work at all, and not
> 
> ecdf(sort(runif(10)))(sort(runif(10)))

I didn't suggest that.  That would be a bad.  All I suggested was 
different sugar to write (function(d) ecdf(d)(d))().

Duncan Murdoch

> 
> There would be no such ambiguity with anonymous functions
> 
> sort(runif(10)) |> \(.) ecdf(.)(.)
> 
> -Deepayan
> 
>> which would be expanded to something equivalent to the other versions:
>> but that makes it quite a bit more complicated.  (Maybe _ or \. should
>> be used instead of ., since those are not legal variable names.)
>>
>> I don't think there should be an attempt to copy magrittr's special
>> casing of how . is used in determining whether to also include the
>> previous value as first argument.
>>
>> Duncan Murdoch
>>
>>
>>>
>>> Best,
>>> Hiroaki Yutani
>>>
>>> 2020?12?4?(?) 20:51 Duncan Murdoch <murdoch.duncan at gmail.com>:
>>>>
>>>> Just saw this on the R-devel news:
>>>>
>>>>
>>>> R now provides a simple native pipe syntax ?|>? as well as a shorthand
>>>> notation for creating functions, e.g. ?\(x) x + 1? is parsed as
>>>> ?function(x) x + 1?. The pipe implementation as a syntax transformation
>>>> was motivated by suggestions from Jim Hester and Lionel Henry. These
>>>> features are experimental and may change prior to release.
>>>>
>>>>
>>>> This is a good addition; by using "|>" instead of "%>%" there should be
>>>> a chance to get operator precedence right.  That said, the ?Syntax help
>>>> topic hasn't been updated, so I'm not sure where it fits in.
>>>>
>>>> There are some choices that take a little getting used to:
>>>>
>>>>    > mtcars |> head
>>>> Error: The pipe operator requires a function call or an anonymous
>>>> function expression as RHS
>>>>
>>>> (I need to say mtcars |> head() instead.)  This sometimes leads to error
>>>> messages that are somewhat confusing:
>>>>
>>>>    > mtcars |> magrittr::debug_pipe |> head
>>>> Error: function '::' not supported in RHS call of a pipe
>>>>
>>>> but
>>>>
>>>> mtcars |> magrittr::debug_pipe() |> head()
>>>>
>>>> works.
>>>>
>>>> Overall, I think this is a great addition, though it's going to be
>>>> disruptive for a while.
>>>>
>>>> Duncan Murdoch
>>>>
>>>> ______________________________________________
>>>> R-devel at r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>> ______________________________________________
>>> R-devel at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] New pipe operator
Duncan Murdoch