Hi John, Thanks, but the Bizzaro pipe comes with many flaws though : * It's not a single operator * It has a different precedence * It cannot be used in a subcall * The variable assigned to must be on the right * It doesn't trigger indentation when going to the line * It creates/overwrite a `.` variable in the worksace. And it doesn't deal gracefully with some lazy evaluation edge cases such as : compose <- function(f, g) { function(x) g(f(x)) } plus1 <- function(x) x + 1 plus2 <- plus1 %.% compose(.,plus1) plus2(5) #> [1] 7 plus1 ->.; compose(.,plus1) -> .; . -> plus2 plus2(5) #> Error: C stack usage 15923776 is too close to the limit What I propose on the other hand can always substitute any existing proper pipe in their standard feature, as long as the dot is made explicit. Best regards, Antoine Le sam. 5 oct. 2019 ? 16:59, John Mount <jmount at win-vector.com> a ?crit :> Actually, base R already has a pipe fairly close to the one you describe: > ->.; > > iris ->.; head(.) ->.; dim(.) > # [1] 6 5 > > I've called it the Bizarro pipe ( > http://www.win-vector.com/blog/2016/12/magrittrs-doppelganger/ ), and for > some reason we chickened out and didn't spend time on it in the dot pipe > paper ( https://journal.r-project.org/archive/2018/RJ-2018-042/index.html > ). > > For documentation Bizarro pipe has the advantage that one can work out how > it works from the application itself, with out reference to a defining > function. > > On Oct 5, 2019, at 7:34 AM, Ant F <antoine.fabri at gmail.com> wrote: > > Dear R-devel, > > The most popular piping operator sits in the package `magrittr` and is used > by a huge amount of users, and imported /reexported by more and more > packages too. > > Many workflows don't even make much sense without pipes nowadays, so the > examples in the doc will use pipes, as do the README, vignettes etc. I > believe base R could have a piping operator so packages can use a pipe in > their code or doc and stay dependency free. > > I don't suggest an operator based on complex heuristics, instead I suggest > a very simple and fast one (>10 times than magrittr in my tests) : > > `%.%` <- function (e1, e2) { > eval(substitute(e2), envir = list(. = e1), enclos = parent.frame()) > } > > iris %.% head(.) %.% dim(.) > #> [1] 6 5 > > The difference with magrittr is that the dots must all be explicit (which > sits with the choice of the name), and that special magrittr features such > as assignment in place and building functions with `. %>% head() %>% dim()` > are not supported. > > Edge cases are not surprising: > > ``` > x <- "a" > x %.% quote(.) > #> . > x %.% substitute(.) > #> [1] "a" > > f1 <- function(y) function() eval(quote(y)) > f2 <- x %.% f1(.) > f2() > #> [1] "a" > ``` > > Looking forward for your thoughts on this, > > Antoine > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > > > --------------- > John Mount > http://www.win-vector.com/ > Our book: Practical Data Science with R > https://www.manning.com/books/practical-data-science-with-r-second-edition > <http://www.manning.com/zumel/> > > > > >[[alternative HTML version deleted]]
Many of those issues can be dealt with by introducing curly braces: compose <- function(f, g) { function(x) g(f(x)) } plus1 <- function(x) x + 1 plus2 <- { plus1 ->.; compose(., plus1) } plus2(5) # [1] 7 And a lot of that is a point to note: we may not all agree on what cases are corner cases, and which ones should be handled in a given way.> On Oct 5, 2019, at 8:48 AM, Ant F <antoine.fabri at gmail.com> wrote: > > Hi John, > > Thanks, but the Bizzaro pipe comes with many flaws though : > * It's not a single operator > * It has a different precedence > * It cannot be used in a subcall > * The variable assigned to must be on the right > * It doesn't trigger indentation when going to the line > * It creates/overwrite a `.` variable in the worksace. > > And it doesn't deal gracefully with some lazy evaluation edge cases such as : > > compose <- function(f, g) { function(x) g(f(x)) } > plus1 <- function(x) x + 1 > > plus2 <- plus1 %.% compose(.,plus1) > plus2(5) > #> [1] 7 > > plus1 ->.; compose(.,plus1) -> .; . -> plus2 > plus2(5) > #> Error: C stack usage 15923776 is too close to the limit > > What I propose on the other hand can always substitute any existing proper pipe in their standard feature, as long as the dot is made explicit. > > Best regards, > > Antoine > > > > Le sam. 5 oct. 2019 ? 16:59, John Mount <jmount at win-vector.com <mailto:jmount at win-vector.com>> a ?crit : > Actually, base R already has a pipe fairly close to the one you describe: ->.; > > iris ->.; head(.) ->.; dim(.) > # [1] 6 5 > > I've called it the Bizarro pipe ( http://www.win-vector.com/blog/2016/12/magrittrs-doppelganger/ <http://www.win-vector.com/blog/2016/12/magrittrs-doppelganger/> ), and for some reason we chickened out and didn't spend time on it in the dot pipe paper ( https://journal.r-project.org/archive/2018/RJ-2018-042/index.html <https://journal.r-project.org/archive/2018/RJ-2018-042/index.html> ). > > For documentation Bizarro pipe has the advantage that one can work out how it works from the application itself, with out reference to a defining function. > >> On Oct 5, 2019, at 7:34 AM, Ant F <antoine.fabri at gmail.com <mailto:antoine.fabri at gmail.com>> wrote: >> >> Dear R-devel, >> >> The most popular piping operator sits in the package `magrittr` and is used >> by a huge amount of users, and imported /reexported by more and more >> packages too. >> >> Many workflows don't even make much sense without pipes nowadays, so the >> examples in the doc will use pipes, as do the README, vignettes etc. I >> believe base R could have a piping operator so packages can use a pipe in >> their code or doc and stay dependency free. >> >> I don't suggest an operator based on complex heuristics, instead I suggest >> a very simple and fast one (>10 times than magrittr in my tests) : >> >> `%.%` <- function (e1, e2) { >> eval(substitute(e2), envir = list(. = e1), enclos = parent.frame()) >> } >> >> iris %.% head(.) %.% dim(.) >> #> [1] 6 5 >> >> The difference with magrittr is that the dots must all be explicit (which >> sits with the choice of the name), and that special magrittr features such >> as assignment in place and building functions with `. %>% head() %>% dim()` >> are not supported. >> >> Edge cases are not surprising: >> >> ``` >> x <- "a" >> x %.% quote(.) >> #> . >> x %.% substitute(.) >> #> [1] "a" >> >> f1 <- function(y) function() eval(quote(y)) >> f2 <- x %.% f1(.) >> f2() >> #> [1] "a" >> ``` >> >> Looking forward for your thoughts on this, >> >> Antoine >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-devel at r-project.org <mailto:R-devel at r-project.org> mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel <https://stat.ethz.ch/mailman/listinfo/r-devel> > > --------------- > John Mount > http://www.win-vector.com/ <http://www.win-vector.com/> > Our book: Practical Data Science with R https://www.manning.com/books/practical-data-science-with-r-second-edition <http://www.manning.com/zumel/> > > > >--------------- John Mount http://www.win-vector.com/ <http://www.win-vector.com/> Our book: Practical Data Science with R https://www.manning.com/books/practical-data-science-with-r-second-edition <http://www.manning.com/zumel/> [[alternative HTML version deleted]]
Hello, R is a functional language, pipes are not. There are even higher order functions such as [1] and [2]. Besides, packages are part of R, R couldn't live without them. I find pipes a good idea but I also find it better not to have them as part of base R. If you want to use them, load a package, if you don't, don't. This simple. As for your example, compose, there is a StackOverflow question on it. See this answer [3]. [1] https://stat.ethz.ch/R-manual/R-devel/library/base/html/funprog.html [2] https://stat.ethz.ch/R-manual/R-devel/library/base/html/Recall.html [3] https://stackoverflow.com/a/52465956/8245406 Hope this helps, Rui Barradas ?s 16:48 de 05/10/19, Ant F escreveu:> Hi John, > > Thanks, but the Bizzaro pipe comes with many flaws though : > * It's not a single operator > * It has a different precedence > * It cannot be used in a subcall > * The variable assigned to must be on the right > * It doesn't trigger indentation when going to the line > * It creates/overwrite a `.` variable in the worksace. > > And it doesn't deal gracefully with some lazy evaluation edge cases such as > : > > compose <- function(f, g) { function(x) g(f(x)) } > plus1 <- function(x) x + 1 > > plus2 <- plus1 %.% compose(.,plus1) > plus2(5) > #> [1] 7 > > plus1 ->.; compose(.,plus1) -> .; . -> plus2 > plus2(5) > #> Error: C stack usage 15923776 is too close to the limit > > What I propose on the other hand can always substitute any existing proper > pipe in their standard feature, as long as the dot is made explicit. > > Best regards, > > Antoine > > > > Le sam. 5 oct. 2019 ? 16:59, John Mount <jmount at win-vector.com> a ?crit : > >> Actually, base R already has a pipe fairly close to the one you describe: >> ->.; >> >> iris ->.; head(.) ->.; dim(.) >> # [1] 6 5 >> >> I've called it the Bizarro pipe ( >> http://www.win-vector.com/blog/2016/12/magrittrs-doppelganger/ ), and for >> some reason we chickened out and didn't spend time on it in the dot pipe >> paper ( https://journal.r-project.org/archive/2018/RJ-2018-042/index.html >> ). >> >> For documentation Bizarro pipe has the advantage that one can work out how >> it works from the application itself, with out reference to a defining >> function. >> >> On Oct 5, 2019, at 7:34 AM, Ant F <antoine.fabri at gmail.com> wrote: >> >> Dear R-devel, >> >> The most popular piping operator sits in the package `magrittr` and is used >> by a huge amount of users, and imported /reexported by more and more >> packages too. >> >> Many workflows don't even make much sense without pipes nowadays, so the >> examples in the doc will use pipes, as do the README, vignettes etc. I >> believe base R could have a piping operator so packages can use a pipe in >> their code or doc and stay dependency free. >> >> I don't suggest an operator based on complex heuristics, instead I suggest >> a very simple and fast one (>10 times than magrittr in my tests) : >> >> `%.%` <- function (e1, e2) { >> eval(substitute(e2), envir = list(. = e1), enclos = parent.frame()) >> } >> >> iris %.% head(.) %.% dim(.) >> #> [1] 6 5 >> >> The difference with magrittr is that the dots must all be explicit (which >> sits with the choice of the name), and that special magrittr features such >> as assignment in place and building functions with `. %>% head() %>% dim()` >> are not supported. >> >> Edge cases are not surprising: >> >> ``` >> x <- "a" >> x %.% quote(.) >> #> . >> x %.% substitute(.) >> #> [1] "a" >> >> f1 <- function(y) function() eval(quote(y)) >> f2 <- x %.% f1(.) >> f2() >> #> [1] "a" >> ``` >> >> Looking forward for your thoughts on this, >> >> Antoine >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> >> --------------- >> John Mount >> http://www.win-vector.com/ >> Our book: Practical Data Science with R >> https://www.manning.com/books/practical-data-science-with-r-second-edition >> <http://www.manning.com/zumel/> >> >> >> >> >> > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
On Sat, 5 Oct 2019 at 18:10, Rui Barradas <ruipbarradas at sapo.pt> wrote:> > R is a functional language, pipes are not.How would you classify them? Pipes are analogous to function composition. In that sense, they are more functional than classes, and R does have classes. Anyway, I don't see "purity" as a valid argument either in favour or against any given feature. Language classification may be useful for theorists, but certainly not for practitioners. I?aki
Hi Rui,> R is a functional language, pipes are not. There are even higher orderfunctions such as [1] and [2]. If they can be build in R, either R is not a functional language, or pipes are part of a functional language. Could you elaborate ? What point would you make against pipes that you couldn't make about other operators or functions leveraging lazy evaluation ? I don't understand either the references to Negate() and Recall(). I actually think that there are few things more "functional" than using pipes :).> Besides, packages are part of R, R couldn't live without them. I find > pipes a good idea but I also find it better not to have them as part of > base R. If you want to use them, load a package, if you don't, don't. > This simple.Simple enough, but more complicated than necessary. I believe it's a fair argument to point than pipes are different. They don't DO anything and yet are used by thousands of packages. They are largely viewed as part of R and some users are surprised no to find them in base R, in the remaining users many don't even know that they come from magrittr but think they come from dplyr. The fact that it feels odd to attach a package only to use the pipe is highlighted by the fact that thousands of packages reexport it , see https://github.com/search?q=filename%3Autils-pipe.R+magrittr . I don't think it can be said of any other function. Package developers could still use `usethis::use_pipe()` if they want to associate their package with magrittr's pipe, but they wouldn't "need" it to suggest to user than piping is recommend way of using their functions in sequence, and this would mean less red ink saying that this `%>%` pipe was masked by that other `%>%` pipe. I like the design of magrittr's pipe a lot and I'd continue to use it either way, but I would write documentation and even functions with `%.%` if it was available, without worrying about dependencies, and less worried about suboptimal performance. Best regards, Antoine Le sam. 5 oct. 2019 ? 18:03, Rui Barradas <ruipbarradas at sapo.pt> a ?crit :> Hello, > > R is a functional language, pipes are not. There are even higher order > functions such as [1] and [2]. > Besides, packages are part of R, R couldn't live without them. I find > pipes a good idea but I also find it better not to have them as part of > base R. If you want to use them, load a package, if you don't, don't. > This simple. > > As for your example, compose, there is a StackOverflow question on it. > See this answer [3]. > > [1] https://stat.ethz.ch/R-manual/R-devel/library/base/html/funprog.html > [2] https://stat.ethz.ch/R-manual/R-devel/library/base/html/Recall.html > [3] https://stackoverflow.com/a/52465956/8245406 > > Hope this helps, > > Rui Barradas > > ?s 16:48 de 05/10/19, Ant F escreveu: > > Hi John, > > > > Thanks, but the Bizzaro pipe comes with many flaws though : > > * It's not a single operator > > * It has a different precedence > > * It cannot be used in a subcall > > * The variable assigned to must be on the right > > * It doesn't trigger indentation when going to the line > > * It creates/overwrite a `.` variable in the worksace. > > > > And it doesn't deal gracefully with some lazy evaluation edge cases such > as > > : > > > > compose <- function(f, g) { function(x) g(f(x)) } > > plus1 <- function(x) x + 1 > > > > plus2 <- plus1 %.% compose(.,plus1) > > plus2(5) > > #> [1] 7 > > > > plus1 ->.; compose(.,plus1) -> .; . -> plus2 > > plus2(5) > > #> Error: C stack usage 15923776 is too close to the limit > > > > What I propose on the other hand can always substitute any existing > proper > > pipe in their standard feature, as long as the dot is made explicit. > > > > Best regards, > > > > Antoine > > > > > > > > Le sam. 5 oct. 2019 ? 16:59, John Mount <jmount at win-vector.com> a ?crit > : > > > >> Actually, base R already has a pipe fairly close to the one you > describe: > >> ->.; > >> > >> iris ->.; head(.) ->.; dim(.) > >> # [1] 6 5 > >> > >> I've called it the Bizarro pipe ( > >> http://www.win-vector.com/blog/2016/12/magrittrs-doppelganger/ ), and > for > >> some reason we chickened out and didn't spend time on it in the dot pipe > >> paper ( > https://journal.r-project.org/archive/2018/RJ-2018-042/index.html > >> ). > >> > >> For documentation Bizarro pipe has the advantage that one can work out > how > >> it works from the application itself, with out reference to a defining > >> function. > >> > >> On Oct 5, 2019, at 7:34 AM, Ant F <antoine.fabri at gmail.com> wrote: > >> > >> Dear R-devel, > >> > >> The most popular piping operator sits in the package `magrittr` and is > used > >> by a huge amount of users, and imported /reexported by more and more > >> packages too. > >> > >> Many workflows don't even make much sense without pipes nowadays, so the > >> examples in the doc will use pipes, as do the README, vignettes etc. I > >> believe base R could have a piping operator so packages can use a pipe > in > >> their code or doc and stay dependency free. > >> > >> I don't suggest an operator based on complex heuristics, instead I > suggest > >> a very simple and fast one (>10 times than magrittr in my tests) : > >> > >> `%.%` <- function (e1, e2) { > >> eval(substitute(e2), envir = list(. = e1), enclos = parent.frame()) > >> } > >> > >> iris %.% head(.) %.% dim(.) > >> #> [1] 6 5 > >> > >> The difference with magrittr is that the dots must all be explicit > (which > >> sits with the choice of the name), and that special magrittr features > such > >> as assignment in place and building functions with `. %>% head() %>% > dim()` > >> are not supported. > >> > >> Edge cases are not surprising: > >> > >> ``` > >> x <- "a" > >> x %.% quote(.) > >> #> . > >> x %.% substitute(.) > >> #> [1] "a" > >> > >> f1 <- function(y) function() eval(quote(y)) > >> f2 <- x %.% f1(.) > >> f2() > >> #> [1] "a" > >> ``` > >> > >> Looking forward for your thoughts on this, > >> > >> Antoine > >> > >> [[alternative HTML version deleted]] > >> > >> ______________________________________________ > >> R-devel at r-project.org mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-devel > >> > >> > >> --------------- > >> John Mount > >> http://www.win-vector.com/ > >> Our book: Practical Data Science with R > >> > https://www.manning.com/books/practical-data-science-with-r-second-edition > >> <http://www.manning.com/zumel/> > >> > >> > >> > >> > >> > > > > [[alternative HTML version deleted]] > > > > ______________________________________________ > > R-devel at r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > >[[alternative HTML version deleted]]