Current best practice on use of pipe within package functions

Years ago I recall reading that use of the pipe (%>%) within R package functions was discouraged and it was better to only use it for interactive use. I believe the justification was that it makes debugging trickier because the call stack can be confusing. I’ve gotten in the habit of not using the pipe in package development, but I’m curious what the current best practices is, do other package developers here typically avoid the pipe in this context? Thanks!

Debugging/error messages/stack traces were known to be problematic with the magrittr pipe. The new base R pipe is really just a syntax transformation on the R parser side of things. In other words, foo |> bar() and bar(foo) are completely equivalent and you will get identical errors and stack traces, if one should occur.

However, foo %>% bar() and bar(foo) are NOT the same from the R parser side of things. I also avoided the magrittr pipe in packages for this reason, but the base R pipe does not suffer from the same issue and should be generally safe to use in packages.

A short reprex to show how the base pipe actually just does a syntax transformation:

library(magrittr)

bar <- function(x) {
  stop('This is not working!')
}
bar(foo)
#> Error in bar(foo): This is not working!
foo |> bar()
#> Error in bar(foo): This is not working!
foo %>% bar()
#> Error in bar(.): This is not working!

Hope this is helpful.

1 Like