[Rd] Generalised piping into operators

Duncan Murdoch murdoch@dunc@n @end|ng |rom gm@||@com
Fri Apr 21 15:52:37 CEST 2023


On 21/04/2023 4:35 a.m., Michael Milton wrote:
> I just checked out R-devel and noticed that the new "pipe extractor"
> capability coming in 4.3 only works for the 4 extractor operators, but no
> other standard operators like +, *, %*% etc, meaning that e.g. mtcars |>
> as.matrix() |> _ + 1 |> colMeans() is a syntax error. In addition, we are
> still subject to the restriction that the functions on the RHS of a pipe
> can't have special names, so mtcars |> as.matrix() |> `+`(1) |> colMeans() is
> also a syntax error.
> 
> Either option would be great, as I find it much cleaner to coordinate a
> sequence of function calls using pipes rather than nested function calls or
> using temporary variables.
> 
> May I enquire why both of these expressions are disallowed, and if it might
> be possible to help remove one or both of these restrictions? There is some
> discussion at
> https://stat.ethz.ch/pipermail/r-devel/2020-December/080210.html but the
> thread is mostly concerned with other things like the placeholder and
> whether or not parentheses can be omitted. My naive view is that piping
> into a special operator function like `+` would be the least ambiguous: `+`
> presumably parses to the same type of token as `colMeans` does, so the
> function parse tree seems like it would work fine if this was allowed in a
> pipe.

If it were allowed, people would expect expressions like yours to work, 
but as ?Syntax says, your pipe would actually be parsed as something like

   (mtcars |> as.matrix() |> _) + (1 |> colMeans())

because the |> operator has higher precedence than +.

Since parens would be needed somewhere to override this, you may as well 
type

   (as.matrix(mtcars) + 1) |> colMeans()

which is both shorter and arguably clearer than

   mtcars |> as.matrix() |> (_ + 1) |> colMeans()

Duncan Murdoch



More information about the R-devel mailing list