tidyverse / purrr

A functional programming toolkit for R
https://purrr.tidyverse.org/
Other
1.28k stars 272 forks source link

FR: compose_pipe for a more intuitive left-to-right version of compose #1056

Closed tripartio closed 1 year ago

tripartio commented 1 year ago

I have only recently discovered the composeadverb, so my apologies in advance if a similar feature request has already been made (but I did not find anything when I searched past issues).

First of all, I fully understand and agree with the decision that composeshould compose its input functions from right-to-left as in standard mathematics. I consider this a difficult decision because most tidyverse users would probably prefer a left-to-right implementation, but I agree that the mathematical standard should take precedence.

That said, a right-to-left compose is counterintuitive for tidyverse users like myself who prefer left-to-right pipes. compose(..., .dir = "forward") is an awkward function signature when that is what I would use every time. So, my simple solution is that I have a tiny function in my personal R utilities file:

# purrr::compose with order of functions in left-to-right (pipe) order
compose_pipe <- function(..., .dir = NULL) {  
  if (is.null(.dir)) {
    .dir <- 'forward'
  }
  purrr::compose(..., .dir = .dir)
}

So, this works for me, but I would like to propose to generalize this (or a similar) solution for purrr.

The quick and simple solution would be to add a similar compose_pipe function (or some other name that might be decided) to purrr that defaults to a left-to-right compose. My argument for adding such a function is:

If this suggestion is accepted, then I would go further and then suggest that compose_pipe should become the reference implementation and that it should call compose, rather than my current workaround above. This is because if, as I suspect, most programmers would use compose_pipe rather than compose, then it would make sense to make compose_pipe the base call so that it could execute faster, rather than vice versa.

If not for the last suggestion, my suggestion for compose_pipe could have been a simple pull request. But if compose_pipe would become the base function from which the current compose function would be called, then the change would be not quite as trivial (it should still be quite easy, but it would require careful testing).

hadley commented 1 year ago

I'm generally no longer a big fan of functions like compose(), because I think the vast majority of readers are better served by just explicitly composing the functions (which is particularly easy with the pipe).