Re: [Rd] New pipe operator
> [Duncan Murdoch responding to...] > [... Mark Bravington's proposals for placeholders and anonymous functions] > > x |> foo( _PIPE_) # placeholder > > x |> bah( otherarg, _PIPE_)# placeholder > > x |> { y <- _PIPE_+1; _PIPE_ / y } # anonymous function > [DM] About your proposal [specifically, the anonymous function bit]: > I don't find it attractive, but I can see that some people would. But I > don't think it's necessary to put it into the base parser. Other than > using an illegal name, there doesn't seem to be a reason you couldn't > write a small function to convert your placeholder proposal to a call to > a function. So instead of typing > x |> { y <- _PIPE_+1; _PIPE_ / y } > you would type > x |> forpipe({ y <- PIPE_+1; PIPE_ / y }) > I don't think "forpipe" is the right name here. I proposed a generic > "as.call" before, but I don't like that one either. I'm still trying to > think of a good name, and whether or not it makes sense for it to be > generic. Right, yes. Actually that was part of my first email: I had x |> _ANON_({ y <- _PIPE_+1; _PIPE_ / y }) I deliberately picked otherwise-illegal names, to prevent extrapipular abuse, but that's not a big deal. Second email gives that option as well as curly-brace version. It's true that there's no *need* to change the base parser in order to get the functionality of your 'forpipe' / my '_ANON_'--- but pipes are really about convenience, so "need" becomes quite subjective; perhaps the curly-brace version, or something else, is attractive enough to warrant it (I don't know). And it seems like the new pipe-aware parser is already having to deal differently with expressions inside a pipe vs outside. However, I was also discussing non-anonymous function calls in pipes, and arguing that they should require (or at least be able to use) a reserved-word placeholder (PIPE_ or whatever)--- EG x |> match( LETTERS, _PIPE_) # non-first arg So that's a separate part of my proposal. If I was king I actually wouldn't let people do x |> head and would force them instead to do x |> head( _PIPE_) but, clearly, I am not. > But the point is that we don't need to choose just one from all the > proposed replacements for anonymous function syntax, we can try them out > and see which ones we like. We might end up with more than one (like we > have at least 4 different high level graphics paradigms!), and that's > not the end of the world. Good point. Multiple options is no disaster, and experiments are excellent--- though once things get embedded in R, it's hard to pull them out... However, aren't we limited to experimenting within the confines of the current pipe-aware parser? Many of the suggestions on this topic seem to go beyond that (including mine). EG I *think*, subject to correction, that - you're right that 'forpipe'/'_ANON_' can be implemented to work with the current pipe-aware parser - But, the curly-brace version would require a parser change - and the use of a reserved-word placeholder also isn't possible as-is If there's some way to try those things out, it would be great. cheers Mark Mark Bravington CSIRO Marine Lab Hobart Australia From: Duncan Murdoch Sent: Wednesday, 9 December 2020 09:28 To: Bravington, Mark (Data61, Hobart); Gabor Grothendieck; Gabriel Becker Cc: r-devel@r-project.org Subject: Re: [Rd] New pipe operator First, one comment: You're right about the illegality of _PIPE_ as a name, I had misremembered the rule. About your proposal: I don't find it attractive, but I can see that some people would. But I don't think it's necessary to put it into the base parser. Other than using an illegal name, there doesn't seem to be a reason you couldn't write a small function to convert your placeholder proposal to a call to a function. So instead of typing x |> { y <- _PIPE_+1; _PIPE_ / y } you would type x |> forpipe({ y <- PIPE_+1; PIPE_ / y }) I don't think "forpipe" is the right name here. I proposed a generic "as.call" before, but I don't like that one either. I'm still trying to think of a good name, and whether or not it makes sense for it to be generic. But the point is that we don't need to choose just one from all the proposed replacements for anonymous function syntax, we can try them out and see which ones we like. We might end up with more than one (like we have at least 4 different high level graphics paradigms!), and that's not the end of the world. Duncan Murdoch On 08/12/2020 4:26 p.m., Bravington, Mark (Data61, Hobart) wrote: >>> On 06/12/2020 8:22 p.m., Bravington, Mark (Data61, Hobart) wrote: >> (and Duncan Murdoch responded, as below) > > It still seems to me that placeholders are viable and unambiguous (only as > things in RHS of pipes), and that something like > > x |> foo( _PIPE_) > x |> bah( otherarg, _PIPE_) > x |> { y <- _PIPE_+1; _PIPE_ / y } # anonymous function > > would be a vi
Re: [Rd] Ignore Sites Option For libPaths
On 9 December 2020 at 02:00, Dario Strbenac wrote: | That seems like a straightforward and reasonable thing to do, but: | | ~$ R_LIBS="/tmp" R_LIBS_SITE="/var" Rscript -e 'print(.libPaths())' | [1] "/dora/nobackup/biostat/Rpackages/v4" "/dora/users/course/splus/library/R" | [3] "/usr/lib/R/site-library" "/usr/lib/R/library" Hm. Maybe you have code in RHOME/etc/* or in HOME to set some of these? The (very detailed) description of what happens when is in help(Startup) which is a great resource but as dense as they get. My example came from my Ubuntu 20.04 box where I set nothing apart from not using a ~/R/ path. Also try "R -q -e 'print(.libPaths())'" with these switches to narrow it down: --no-environ Don't read the site and user environment files --no-site-fileDon't read the site-wide Rprofile --no-init-fileDon't read the user R profile | /tmp and /var exist of course. Right, I didn't stress that but the choice made it clear. I still think you should be able to tune this with just base R. Cheers, Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Ignore Sites Option For libPaths
Good day, That seems like a straightforward and reasonable thing to do, but: ~$ R_LIBS="/tmp" R_LIBS_SITE="/var" Rscript -e 'print(.libPaths())' [1] "/dora/nobackup/biostat/Rpackages/v4" "/dora/users/course/splus/library/R" [3] "/usr/lib/R/site-library" "/usr/lib/R/library" /tmp and /var exist of course. -- Dario Strbenac University of Sydney Camperdown NSW 2050 Australia __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Ignore Sites Option For libPaths
Of course you can, but the ability to do something via R code and the ability to do them by wrapping the invocation of R are not similar terms of convenience, IMO. I say that as someone who routinely does both type of thing. ~G On Tue, Dec 8, 2020 at 4:07 PM Dirk Eddelbuettel wrote: > > On 8 December 2020 at 23:00, Dario Strbenac wrote: > | Could .libPaths gain an option to ignore all values other than the > user-specified new parameter? Currently, it takes the union of new and > .Library and .Library.site and there is no way to turn it off. > > Are you use? It is constructed from looking at environment variables you > could set. > > edd@rob:~$ R_LIBS="/tmp" R_LIBS_SITE="/var" Rscript -e > 'print(.libPaths())' > [1] "/tmp" "/var" "/usr/lib/R/library" > edd@rob:~$ > > Dirk > > -- > https://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org > > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Ignore Sites Option For libPaths
On 8 December 2020 at 23:00, Dario Strbenac wrote: | Could .libPaths gain an option to ignore all values other than the user-specified new parameter? Currently, it takes the union of new and .Library and .Library.site and there is no way to turn it off. Are you use? It is constructed from looking at environment variables you could set. edd@rob:~$ R_LIBS="/tmp" R_LIBS_SITE="/var" Rscript -e 'print(.libPaths())' [1] "/tmp" "/var" "/usr/lib/R/library" edd@rob:~$ Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Ignore Sites Option For libPaths
Hi Dario, My switchr package is designed specifically to do what you're describing, and does support excluding site libraries. So clearly I agree it would be useful, but also, it does go against the "concept" of site libraries somewhat. I agree it would be a useful addition with the default to including them, personally. And the patch would be pretty easy to put together. I can put together a patch and add it to bugzilla as a wishlist item and we'll see what thoughts are (unless I hear an emphatic no here, in which case I won't bother, or unless you'd like to take a crack at it yourself). ~G On Tue, Dec 8, 2020 at 3:00 PM Dario Strbenac wrote: > Good day, > > Could .libPaths gain an option to ignore all values other than the > user-specified new parameter? Currently, it takes the union of new and > .Library and .Library.site and there is no way to turn it off. For quick > and convenient troubleshooting that doesn't involve requiring the editing > of configuration files, it would be nice to be able to run > .libPaths(.libPaths()[1], ignoreSiteFiles = TRUE) to limit to only one > folder of R packages. > > > .libPaths() > [1] "/dskh/nobackup/biostat/Rpackages/v4" > "/usr/users/course/splus/library/R" > [3] "/usr/lib/R/site-library" "/usr/lib/R/library" > > .libPaths(.libPaths()[1]) # No option to ignore system-wide folders. > > .libPaths() # Paths are same as before. > [1] "/dskh/nobackup/biostat/Rpackages/v4" > "/usr/users/course/splus/library/R" > [3] "/usr/lib/R/site-library" "/usr/lib/R/library" > > -- > Dario Strbenac > University of Sydney > Camperdown NSW 2050 > Australia > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] Ignore Sites Option For libPaths
Good day, Could .libPaths gain an option to ignore all values other than the user-specified new parameter? Currently, it takes the union of new and .Library and .Library.site and there is no way to turn it off. For quick and convenient troubleshooting that doesn't involve requiring the editing of configuration files, it would be nice to be able to run .libPaths(.libPaths()[1], ignoreSiteFiles = TRUE) to limit to only one folder of R packages. > .libPaths() [1] "/dskh/nobackup/biostat/Rpackages/v4" "/usr/users/course/splus/library/R" [3] "/usr/lib/R/site-library" "/usr/lib/R/library" > .libPaths(.libPaths()[1]) # No option to ignore system-wide folders. > .libPaths() # Paths are same as before. [1] "/dskh/nobackup/biostat/Rpackages/v4" "/usr/users/course/splus/library/R" [3] "/usr/lib/R/site-library" "/usr/lib/R/library" -- Dario Strbenac University of Sydney Camperdown NSW 2050 Australia __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] New pipe operator
First, one comment: You're right about the illegality of _PIPE_ as a name, I had misremembered the rule. About your proposal: I don't find it attractive, but I can see that some people would. But I don't think it's necessary to put it into the base parser. Other than using an illegal name, there doesn't seem to be a reason you couldn't write a small function to convert your placeholder proposal to a call to a function. So instead of typing x |> { y <- _PIPE_+1; _PIPE_ / y } you would type x |> forpipe({ y <- PIPE_+1; PIPE_ / y }) I don't think "forpipe" is the right name here. I proposed a generic "as.call" before, but I don't like that one either. I'm still trying to think of a good name, and whether or not it makes sense for it to be generic. But the point is that we don't need to choose just one from all the proposed replacements for anonymous function syntax, we can try them out and see which ones we like. We might end up with more than one (like we have at least 4 different high level graphics paradigms!), and that's not the end of the world. Duncan Murdoch On 08/12/2020 4:26 p.m., Bravington, Mark (Data61, Hobart) wrote: On 06/12/2020 8:22 p.m., Bravington, Mark (Data61, Hobart) wrote: (and Duncan Murdoch responded, as below) It still seems to me that placeholders are viable and unambiguous (only as things in RHS of pipes), and that something like x |> foo( _PIPE_) x |> bah( otherarg, _PIPE_) x |> { y <- _PIPE_+1; _PIPE_ / y } # anonymous function would be a viable solution that doesn't break syntax. This suggestion expands slightly on my previous post, to deal with anonymous functions without either ugly or cumbersome syntax. Specifically, the parser could expand curly-braces in a pipe RHS like this: x |> {expr} into _ANON_( _PIPE_, {expr})( x) where '_ANON_' itself constructs-and-calls a function with one argument called '_PIPE_' whose body consists of 'expr' (which presumably refers to '_PIPE_') No new weird operators like \(, and the only break with normal syntax is the expansion of curly-braces--- plus treating one symbol, _PIPE_ or any other pre-agreed one perhaps even just _, as a legal name inside a pipe. Now back to my previous post and responding to Duncan's comments: - I don't see the problem with a placeholder--- doesn't it remove all ambiguity? Sure there needs to be a standard unclashable name and people can argue about what that should be, but the following seems clear and flexible... to me, anyway: thing |> foo( _PIPE_) |> # standard bah( arg1, _PIPE_) |> # multi-arg function _ANON_({ x <- sum( _PIPE_); _PIPE_/x + x/_PIPE_ }) # anon function where '_PIPE_' is the ordained name of the placeholder, and '_ANON_' constructs-and-calls a function with single argument '_PIPE_'. There is just one rule (I think...): each pipe-stage must be a *call* involving the argument '_PIPE_'. and (see end) I think the line with _ANON_ above could in fact just be ... |> { x <- sum( _PIPE_); _PIPE_/x + x/_PIPE_ } I believe there's no ambiguity if the placeholder is *only* allowed in the RHS of a pipe expression. Yes--- that's my suggestion: there and only there. Hence an otherwise-illegal name like _PIPE_. I think the ambiguity arises if you allow the same syntax to be used to generate anonymous functions. Agreed; don't allow that outside of pipes. We can't use _PIPE_ as the placeholder, because it's a legal name. Surely _PIPE_ is not a legal R name though? Not in my R4.1.0dev, anyway. Of course, the parser can _make_ it legal *only* in the context of RHS of pipe. Anyway, I'm not suggesting the names must be _PIPE_ and _ANON_--- the name is secondary to the concept. But we could use _. Yes, any unclashable name would do--- though "_" is hard to read (as per complaints about "." as placeholder, which I use in my own code). And I remember back when R decided to disallow "_" as an assignment operator. Which forced me to change about 5 lines of code that wasn't stored in text files, so I wasn't happy--- and the only reason that was ever given to me, was "it's ugly" ! Which is kinda true. However, implementing this makes the parser pretty ugly: its handling of _ depends on the outer context. That context issue is already the case under the current proposal though; eg 'head(10)' in x |> head(10) # really head( , 10) or indeed 'head' in x |> head # actually a call to head(), not a symbol I now agree that leaving out placeholder syntax was the right decision. Others are not so sure! Re operator precedence: thanks for pointing that out, I accept that R's current operator-precedence rules make it impossible for people to cleanly implement their own preferred homemade %my_pipe_op%. All the more reason to be careful with the pipe syntax choice for base-R, of course... Then x |> (_ + 1) + mean(_) could expand unambiguously to (fun
Re: [Rd] New pipe operator
> > On 06/12/2020 8:22 p.m., Bravington, Mark (Data61, Hobart) wrote: > (and Duncan Murdoch responded, as below) It still seems to me that placeholders are viable and unambiguous (only as things in RHS of pipes), and that something like x |> foo( _PIPE_) x |> bah( otherarg, _PIPE_) x |> { y <- _PIPE_+1; _PIPE_ / y } # anonymous function would be a viable solution that doesn't break syntax. This suggestion expands slightly on my previous post, to deal with anonymous functions without either ugly or cumbersome syntax. Specifically, the parser could expand curly-braces in a pipe RHS like this: x |> {expr} into _ANON_( _PIPE_, {expr})( x) where '_ANON_' itself constructs-and-calls a function with one argument called '_PIPE_' whose body consists of 'expr' (which presumably refers to '_PIPE_') No new weird operators like \(, and the only break with normal syntax is the expansion of curly-braces--- plus treating one symbol, _PIPE_ or any other pre-agreed one perhaps even just _, as a legal name inside a pipe. Now back to my previous post and responding to Duncan's comments: > > - I don't see the problem with a placeholder--- doesn't it remove all > > ambiguity? Sure there needs to be a standard unclashable name and people > > can argue about what that should be, but the following seems clear and > > flexible... to me, anyway: > > > > thing |> > > foo( _PIPE_) |> # standard > > bah( arg1, _PIPE_) |> # multi-arg function > > _ANON_({ x <- sum( _PIPE_); _PIPE_/x + x/_PIPE_ }) # anon function > > > > where '_PIPE_' is the ordained name of the placeholder, and '_ANON_' > > constructs-and-calls a function with single argument '_PIPE_'. There is > > just one rule (I think...): each pipe-stage must be a *call* involving the > > argument '_PIPE_'. and (see end) I think the line with _ANON_ above could in fact just be ... |> { x <- sum( _PIPE_); _PIPE_/x + x/_PIPE_ } > I believe there's no ambiguity if the placeholder is *only* allowed in the > RHS of a pipe expression. Yes--- that's my suggestion: there and only there. Hence an otherwise-illegal name like _PIPE_. > I think the ambiguity arises if you allow > the same syntax to be used to generate anonymous functions. Agreed; don't allow that outside of pipes. > We can't use _PIPE_ as the placeholder, because it's a legal name. Surely _PIPE_ is not a legal R name though? Not in my R4.1.0dev, anyway. Of course, the parser can _make_ it legal *only* in the context of RHS of pipe. Anyway, I'm not suggesting the names must be _PIPE_ and _ANON_--- the name is secondary to the concept. > But we could use _. Yes, any unclashable name would do--- though "_" is hard to read (as per complaints about "." as placeholder, which I use in my own code). And I remember back when R decided to disallow "_" as an assignment operator. Which forced me to change about 5 lines of code that wasn't stored in text files, so I wasn't happy--- and the only reason that was ever given to me, was "it's ugly" ! Which is kinda true. > However, implementing this makes the parser pretty ugly: its handling of _ > depends on the outer context. That context issue is already the case under the current proposal though; eg 'head(10)' in x |> head(10) # really head( , 10) or indeed 'head' in x |> head # actually a call to head(), not a symbol > I now agree that leaving out placeholder syntax was the right decision. Others are not so sure! Re operator precedence: thanks for pointing that out, I accept that R's current operator-precedence rules make it impossible for people to cleanly implement their own preferred homemade %my_pipe_op%. All the more reason to be careful with the pipe syntax choice for base-R, of course... > Then >x |> (_ + 1) + mean(_) > could expand unambiguously to >(function(_) (_ + 1) + mean(_))(x) > but >(_ + 1) + mean(_) > shouldn't be taken to be an anonymous function declaration, otherwise > things like >mean(_ |> _) > do become ambiguous: is the second placeholder the argument to the anon > function, or is it the placeholder for the embedded pipe? That wouldn't be allowed in my proposal; the "_ |> _" is illegal because the RHS is not a call. For the whole thing, I'd require x |> _ANON_((_PIPE_ + 1) + mean( _PIPE_)) or the just-curly version x |> { (_PIPE_ + 1) + mean( _PIPE_)} but with the implication that this would parse out to (`_ANON_`( { (_PIPE_ + 1) + mean( _PIPE_)}))( x) > > [*] Definition of _ANON_ could be something like this--- almost certainly > > won't work as-is, this is just to point out that it could be done in > > standard R. > > `_ANON_` <- function( expr) { > > #1. Construct a function with arg '_PIPE_' and body 'expr' > > #2. Construct a call() to that function > > #3. Do the call > > f <- function( `_PIPE_`) NULL > > body( f) <- expr > > environment( f) <- parent.frame() # or something... yes these deta
Re: [Rd] [External] Re: New pipe operator
On Mon, Dec 7, 2020 at 9:09 AM Gabor Grothendieck wrote: > > On Sat, Dec 5, 2020 at 1:19 PM wrote: > > Let's get some experience > > Here is my last SO post using dplyr rewritten to use R 4.1 devel. Seems It occurred to me it would also be interesting to show this example rewritten using John Mount's bizarro pipe (which is clever use of syntax to get the effect of a pipe) with the new \(x) ... This can be done entirely in base R 4.1. It does not use \>, just \(x)... "myfile.csv" ->.; readLines(.) ->.; gsub(r'{(c\(.*?\)|integer\(0\))}', r'{"\1"}', .) ->.; read.csv(text = .) ->.; replace(., 2:3, lapply(.[2:3], \(col) lapply(col, \(x) eval(parse(text = x) ->.; . -> DF __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] [External] anonymous functions
On Mon, Dec 7, 2020 at 12:34 PM wrote: > I don't disagree in principle, but the reality is users want shortcuts > and as a result various packages, in particular tidyverse, have been > providing them. Mostly based on formulas, mostly with significant > issues since formulas weren't designed for this, and mostly > incompatible (tidyverse ones are compatible within tidyverse but not > with others). And of course none work in sapply or lapply. The formulas as functions in the gsubfn package work with nearly any function including sapply and lapply. library(gsubfn) fn$lapply(1:3, ~ x + 1) ## [1] 2 3 4 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] [External] anonymous functions
On 08/12/2020 6:21 a.m., Duncan Murdoch wrote: On 07/12/2020 12:26 p.m., luke-tier...@uiowa.edu wrote: I don't disagree in principle, but the reality is users want shortcuts and as a result various packages, in particular tidyverse, have been providing them. Mostly based on formulas, mostly with significant issues since formulas weren't designed for this, and mostly incompatible (tidyverse ones are compatible within tidyverse but not with others). And of course none work in sapply or lapply. Providing a shorthand in base may help to improve this. You don't have to use it if you don't want to, and you can establish coding standards that disallow it if you like. Here's a suggestion to let people define their own shorthands and work with the current |> definition. Define "as.call" as an S3 generic, with a default definition something like > as.call.default <- function(x, f, ...) f(x, ...) That's probably a bad choice of name for the generic in that it doesn't convert x to a call and it's only useful in a pipe, but I do think the idea of some generic function would be useful. Duncan Murdoch so one could use x |> as.call(mean) to get the same result as x |> mean() or (if working in the tidyverse) x |> as.call(~ .x + 1) to use a method to be provided by rlang or purrr to convert their shorthand into a call that the pipe can work with. We already have the generic as.function, which could be used internally by lapply and sapply for the same sort of purpose. tidyverse has rlang::as_function, so they could pretty easily add methods for as.function if they wanted to allow people to use their shorthand in *apply functions. Duncan Murdoch __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] New pipe operator
I just wanted to pipe in here (HA HA) to say that I agree with Kevin. I've never loved the complicated magrittr rule (which has personally tripped me up a couple of times) and I think the compact inline function syntax provides a more general solution. It is a bit more typing, and it will require a little time for your eyes to get used to the new syntax, but overall I think it's a better solution. In general, I think the base pipe does an excellent job of taking what we've learned from 6 years of magrittr, keeping what has been most successful while discarding complications around the edges. Hadley On Mon, Dec 7, 2020 at 1:05 PM Kevin Ushey wrote: > > IMHO the use of anonymous functions is a very clean solution to the > placeholder problem, and the shorthand lambda syntax makes it much > more ergonomic to use. Pipe implementations that crawl the RHS for > usages of `.` are going to be more expensive than the alternatives. It > is nice that the `|>` operator is effectively the same as a regular R > function call, and given the identical semantics could then also be > reasoned about the same way regular R function calls are. > > I also agree usages of the `.` placeholder can make the code more > challenging to read, since understanding the behavior of a piped > expression then requires scouring the RHS for usages of `.`, which can > be challenging in dense code. Piping to an anonymous function makes > the intent clear to the reader: the programmer is likely piping to an > anonymous function because they care where the argument is used in the > call, and so the reader of code should be aware of that. > > Best, > Kevin > > > > On Mon, Dec 7, 2020 at 10:35 AM Gabor Grothendieck > wrote: > > > > On Mon, Dec 7, 2020 at 12:54 PM Duncan Murdoch > > wrote: > > > An advantage of the current implementation is that it's simple and easy > > > to understand. Once you make it a user-modifiable binary operator, > > > things will go kind of nuts. > > > > > > For example, I doubt if there are many users of magrittr's pipe who > > > really understand its subtleties, e.g. the example in Luke's paper where > > > 1 %>% c(., 2) gives c(1,2), but 1 %>% c(c(.), 2) gives c(1, 1, 2). (And > > > I could add 1 %>% c(c(.), 2, .) and 1 %>% c(c(.), 2, . + 2) to > > > continue the fun.) > > > > The rule is not so complicated. Automatic insertion is done unless > > you use dot in the top level function or if you surround it with > > {...}. It really makes sense since if you use gsub(pattern, > > replacement, .) then surely you don't want automatic insertion and if > > you surround it with { ... } then you are explicitly telling it not > > to. > > > > Assuming the existence of placeholders a possible simplification would > > be to NOT do automatic insertion if { ... } is used and to use it > > otherwise although personally having used it for some time I find the > > existing rule in magrittr generally does what you want. > > > > __ > > R-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel -- http://hadley.nz __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] New pipe operator
Duncan Murdoch: > I agree it's all about call expressions, but they aren't all being > treated equally: > > x |> f(...) > > expands to f(x, ...), while > > x |> `function`(...) > > expands to `function`(...)(x). This is an exception to the rule for Yes, this is the problem. It is trying to handle two different sorts of right hand sides, calls and functions, using only syntax level operations and it really needs to either make use of deeper information or have some method that is available at the syntax level for identifying whether the right hand side is a call or function. In the latter case having two operators would be one way to do it. f <- \(x) x + 1 x |> f() # call x |:> f # function x |:> \(x) x + 1 # function In the other case where deeper information is used there would only be one operator and it would handle all cases but would use more than just syntax level knowledge. R solved these sorts of problems long ago using S3 and other object oriented systems which dispatch different methods based on what the right hand side is. The attempt to avoid using the existing or equivalent mechanisms seems to have led to this problem. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] [External] anonymous functions
On 07/12/2020 12:26 p.m., luke-tier...@uiowa.edu wrote: I don't disagree in principle, but the reality is users want shortcuts and as a result various packages, in particular tidyverse, have been providing them. Mostly based on formulas, mostly with significant issues since formulas weren't designed for this, and mostly incompatible (tidyverse ones are compatible within tidyverse but not with others). And of course none work in sapply or lapply. Providing a shorthand in base may help to improve this. You don't have to use it if you don't want to, and you can establish coding standards that disallow it if you like. Here's a suggestion to let people define their own shorthands and work with the current |> definition. Define "as.call" as an S3 generic, with a default definition something like as.call.default <- function(x, f, ...) f(x, ...) so one could use x |> as.call(mean) to get the same result as x |> mean() or (if working in the tidyverse) x |> as.call(~ .x + 1) to use a method to be provided by rlang or purrr to convert their shorthand into a call that the pipe can work with. We already have the generic as.function, which could be used internally by lapply and sapply for the same sort of purpose. tidyverse has rlang::as_function, so they could pretty easily add methods for as.function if they wanted to allow people to use their shorthand in *apply functions. Duncan Murdoch __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel