iuke-tier@ey m@iii@g oii uiow@@edu
2020-Dec-05 18:10 UTC
[Rd] [External] Re: New pipe operator
We went back and forth on this several times. The key advantage of requiring parentheses is to keep things simple and consistent. Let's get some experience with that. If experience shows requiring parentheses creates too many issues then we can add the option of dropping them later (with special handling of :: and :::). It's easier to add flexibility and complexity than to restrict it after the fact. Best, luke On Sat, 5 Dec 2020, Hugh Parsonage wrote:> I'm surprised by the aversion to > > mtcars |> nrow > > over > > mtcars |> nrow() > > and I think the decision to disallow the former should be > reconsidered. The pipe operator is only going to be used when the rhs > is a function, so there is no ambiguity with omitting the parentheses. > If it's disallowed, it becomes inconsistent with other treatments like > sapply(mtcars, typeof) where sapply(mtcars, typeof()) would just be > noise. I'm not sure why this decision was taken > > If the only issue is with the double (and triple) colon operator, then > ideally `mtcars |> base::head` should resolve to `base::head(mtcars)` > -- in other words, demote the precedence of |> > > Obviously (looking at the R-Syntax branch) this decision was > considered, put into place, then dropped, but I can't see why > precisely. > > Best, > > > Hugh. > > > > > > > > On Sat, 5 Dec 2020 at 04:07, Deepayan Sarkar <deepayan.sarkar at gmail.com> 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))) >> >> 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 >> >> ______________________________________________ >> 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 >-- 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 at uiowa.edu Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu
Luke, When writing a blog post on that, could you please describe performance implications that this new feature will carry? AFAIU, compared to a standard way of using temporary variables, pipes will allow to not increment REFCNT of objects being piped into. Therefore peak memory usage could be lower in some cases. As for brackets required on RHS, I think it makes sense to be consistent and either require brackets for anonymous functions the same way we require for function name, or not require brackets for both of them. Best, Jan On Sat, Dec 5, 2020 at 8:10 PM <luke-tierney at uiowa.edu> wrote:> > We went back and forth on this several times. The key advantage of > requiring parentheses is to keep things simple and consistent. Let's > get some experience with that. If experience shows requiring > parentheses creates too many issues then we can add the option of > dropping them later (with special handling of :: and :::). It's easier > to add flexibility and complexity than to restrict it after the fact. > > Best, > > luke > > On Sat, 5 Dec 2020, Hugh Parsonage wrote: > > > I'm surprised by the aversion to > > > > mtcars |> nrow > > > > over > > > > mtcars |> nrow() > > > > and I think the decision to disallow the former should be > > reconsidered. The pipe operator is only going to be used when the rhs > > is a function, so there is no ambiguity with omitting the parentheses. > > If it's disallowed, it becomes inconsistent with other treatments like > > sapply(mtcars, typeof) where sapply(mtcars, typeof()) would just be > > noise. I'm not sure why this decision was taken > > > > If the only issue is with the double (and triple) colon operator, then > > ideally `mtcars |> base::head` should resolve to `base::head(mtcars)` > > -- in other words, demote the precedence of |> > > > > Obviously (looking at the R-Syntax branch) this decision was > > considered, put into place, then dropped, but I can't see why > > precisely. > > > > Best, > > > > > > Hugh. > > > > > > > > > > > > > > > > On Sat, 5 Dec 2020 at 04:07, Deepayan Sarkar <deepayan.sarkar at gmail.com> 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))) > >> > >> 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 > >> > >> ______________________________________________ > >> 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 > > > > -- > 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 at uiowa.edu > Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
Dear Luke,
In the meantime I checked the R-syntax branch and the docs; they are
very helpful. I would also like to thank you for putting effort into
this feature. Keeping it at the syntax level is also a very smart
decision. However, the current API might not exploit the full power of
the basic idea.
1) Requiring either an anonymous function or a function call, but not
allowing for symbols which point to functions is inconsistent and will
be misleading for non-experts.
foo <- function(x) x
identical(foo, function(x) x)
mtcars |> foo #bang!
mtcars |> function(x) x #fine?
You stated in :
"
Another variation supported by the implementation is that a symbol on
the RHS is interpreted as the name of a function to call with the LHS
as argument:
```r
> quote(x |> f)
f(x)
```
"
So clearly this is not an implementation issue but a design decision.
As a remedy, two different pipe operators could be introduced:
LHS |> RHS -> RHS is treated as a function call
LHS |>> RHS -> RHS is treated as a function
If |>> is used, it would not matter which notation is used for the RHS
expression; the parser would assume it evaluates to a function.
2) Simplified lambda expression:
IMHO in the vast majority of use cases, this is used for single-argument
functions, so parenthesis would not be required. Hence, both forms would
be valid and equivalent:
\x x + 1
\(x) x + 1
3) Function composition:
Allowing for concise composition of functions would be a great feature.
E.g., instead of
foo <- function(x) print(mean(sqrt(x), na.rm = TRUE), digits = 2)
or
foo <- \x {x |> sqrt() |> mean(na.rm = TRUE) |> print(digits = 2)}
one could write
foo <- \x |> sqrt() |> mean(na.rm = TRUE) |> print(digits = 2)
So basically if the lambda argument is followed by a pipe operator, the
pipe chain is transformed to a function body where the first lambda
argument is inserted into the first position of the pipeline.
Best,
Denes
On 12/5/20 7:10 PM, luke-tierney at uiowa.edu wrote:> We went back and forth on this several times. The key advantage of
> requiring parentheses is to keep things simple and consistent.? Let's
> get some experience with that. If experience shows requiring
> parentheses creates too many issues then we can add the option of
> dropping them later (with special handling of :: and :::). It's easier
> to add flexibility and complexity than to restrict it after the fact.
>
> Best,
>
> luke
>
> On Sat, 5 Dec 2020, Hugh Parsonage wrote:
>
>> I'm surprised by the aversion to
>>
>> mtcars |> nrow
>>
>> over
>>
>> mtcars |> nrow()
>>
>> and I think the decision to disallow the former should be
>> reconsidered.? The pipe operator is only going to be used when the rhs
>> is a function, so there is no ambiguity with omitting the parentheses.
>> If it's disallowed, it becomes inconsistent with other treatments
like
>> sapply(mtcars, typeof) where sapply(mtcars, typeof()) would just be
>> noise.? I'm not sure why this decision was taken
>>
>> If the only issue is with the double (and triple) colon operator, then
>> ideally `mtcars |> base::head` should resolve to
`base::head(mtcars)`
>> -- in other words, demote the precedence of |>
>>
>> Obviously (looking at the R-Syntax branch) this decision was
>> considered, put into place, then dropped, but I can't see why
>> precisely.
>>
>> Best,
>>
>>
>> Hugh.
>>
>>
>>
>>
>>
>>
>>
>> On Sat, 5 Dec 2020 at 04:07, Deepayan Sarkar
>> <deepayan.sarkar at gmail.com> 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)))
>>>
>>> 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
>>>
>>> ______________________________________________
>>> 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
>>
>
The following gives an error. 1 |> `+`(2) ## Error: function '+' is not supported in RHS call of a pipe 1 |> `+`() ## Error: function '+' is not supported in RHS call of a pipe but this does work: 1 |> (`+`)(2) ## [1] 3 1 |> (`+`)() ## [1] 1 The error message suggests that this was intentional. It isn't mentioned in ?"|>" On Sat, Dec 5, 2020 at 1:19 PM <luke-tierney at uiowa.edu> wrote:> > We went back and forth on this several times. The key advantage of > requiring parentheses is to keep things simple and consistent. Let's > get some experience with that. If experience shows requiring > parentheses creates too many issues then we can add the option of > dropping them later (with special handling of :: and :::). It's easier > to add flexibility and complexity than to restrict it after the fact. > > Best, > > luke > > On Sat, 5 Dec 2020, Hugh Parsonage wrote: > > > I'm surprised by the aversion to > > > > mtcars |> nrow > > > > over > > > > mtcars |> nrow() > > > > and I think the decision to disallow the former should be > > reconsidered. The pipe operator is only going to be used when the rhs > > is a function, so there is no ambiguity with omitting the parentheses. > > If it's disallowed, it becomes inconsistent with other treatments like > > sapply(mtcars, typeof) where sapply(mtcars, typeof()) would just be > > noise. I'm not sure why this decision was taken > > > > If the only issue is with the double (and triple) colon operator, then > > ideally `mtcars |> base::head` should resolve to `base::head(mtcars)` > > -- in other words, demote the precedence of |> > > > > Obviously (looking at the R-Syntax branch) this decision was > > considered, put into place, then dropped, but I can't see why > > precisely. > > > > Best, > > > > > > Hugh. > > > > > > > > > > > > > > > > On Sat, 5 Dec 2020 at 04:07, Deepayan Sarkar <deepayan.sarkar at gmail.com> 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))) > >> > >> 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 > >> > >> ______________________________________________ > >> 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 > > > > -- > 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 at uiowa.edu > Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel-- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com
On Sat, Dec 5, 2020 at 1:19 PM <luke-tierney at uiowa.edu> wrote:> Let's get some experienceHere is my last SO post using dplyr rewritten to use R 4.1 devel. Seems not too bad. Was able to work around the placeholder for gsub by specifying the arg names and used \(...)... elsewhere. This does not address the inconsistency discussed though. I have indented by 2 spaced in case the email wraps around. The objective is to read myfile.csv including columns that contain c(...) and integer(0), parsing and evaluating them. # taken from: # https://stackoverflow.com/questions/65174764/reading-in-a-csv-that-contains-vectors-cx-y-in-r/65175172#65175172 # create input file for testing Lines <- "\"col1\",\"col2\",\"col3\"\n\"a\",1,integer(0)\n\"c\",c(3,4),5\n\"e\",6,7\n" cat(Lines, file = "myfile.csv") ######################################################################### # base R 4.1 (devel) DF <- "myfile.csv" |> readLines() |> gsub(pattern = r'{(c\(.*?\)|integer\(0\))}', replacement = r'{"\1"}') |> \(.) read.csv(text = .) |> \(.) replace(., 2:3, lapply(.[2:3], \(col) lapply(col, \(x) eval(parse(text = x))))) ######################################################################### # dplyr/magrittr library(dplyr) DF <- "myfile.csv" %>% readLines %>% gsub(r'{(c\(.*?\)|integer\(0\))}', r'{"\1"}', .) %>% { read.csv(text = .) } %>% mutate(across(2:3, ~ lapply(., function(x) eval(parse(text = x)))))