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 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 >
On 12/4/20 3:05 PM, Duncan Murdoch wrote:> ... > > It's tempting to suggest it should allow something like > > ? mtcars |> subset(cyl == 4) |> lm(mpg ~ disp, data = .) > > 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 support the idea of using an underscore (_) as the placeholder symbol. Syntactic sugars work the the best if 1) they require less keystrokes and/or 2) are easier to read compared to the "normal" syntax, and 3) can not lead to unexpected bugs (which is a major problem with the magrittr pipe). Using '_' fulfills all of these criteria since '_' can not clash with any variable in the environment. Denes
Am 04.12.20 um 15:05 schrieb Duncan Murdoch:> 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.Thank you for this example. I agree but think that the new base R pipe might trigger some initial confusion as well: mtcars |> function(x) dim(x)[1L] #> [1] 32 mtcars |> nrow #> Error: The pipe operator requires a function call or an anonymous function expression as RHS The RHS evaluates to the same thing in both cases (bar attributes and environments), but only the anonymous variant is supported. I admit that I haven't used %>% before; maybe the above discrepancy is less irritating for those who have. The error message is clear though! That said, I think the code is very readable when piping explicitly into an anonymous function and I also prefer mtcars |> nrow() over mtcars |> nrow, because we are visibly calling something. IMO, readability is lost when using the cryptic short-hand notation mtcars |> \(x) dim(x)[1L] which really only saves 7 letters.> 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 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 guess "_" as a placeholder would be difficult to implement precisely because it currently is a syntax error. Best regards, Sebastian Meyer> 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
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