16

R 4.1.0 famously introduced the |> ("base pipe") operator and Haskell-like lambda function syntax.

I thought it would be possible to combine the two like this:

c(1, 2, 3) |> \(x) 2 * x

This fails for me with:

Error: function 'function' not supported in RHS call of a pipe

I thus assume this is not valid syntax? This works:

c(1, 2, 3) |> (\(x) 2 * x)()

Is there a more elegant way to chain the pipe and the new lambda functions?

utubun
  • 4,400
  • 1
  • 14
  • 17
nevrome
  • 1,471
  • 1
  • 13
  • 28
  • This tweet here compiles a list of options how the pipe can be combined with lambda functions: https://twitter.com/bmwiernik/status/1398611489901121536?s=09 – nevrome May 30 '21 at 11:00
  • 1
    What is the rationale for this design decision? (i.e., given that the parser can tell that there is a function in the RHS call of a pipe, why doesn't the parser just assume that we would want to apply the function to the left hand side even without parentheses?) – bryn Jun 24 '21 at 00:30

3 Answers3

16

I think the most elegant way is with curly braces:

c(1, 2, 3) |> {\(x) 2 * x}()

but this works too:

c(1, 2, 3) |> (\(x) 2 * x)()
vonjd
  • 4,202
  • 3
  • 44
  • 68
11

That's the limitation of native pipe. You just include () after the function name, this is different from magrittr.

# native pipe
foo |> bar()
# magrittr pipe
foo %>% bar

That is to say, \(x) 2*x is equivalent to the old anonymous function syntax function (x) 2*x, but similar to named functions, when used on the RHS of native pipe, you must include ().

Lucius Hu
  • 287
  • 4
  • 10
  • 3
    I see - I hoped for an even more concise syntax, but I'm sure the limitations are there for a reason. – nevrome May 21 '21 at 08:36
0

Another reasonable approach would be:

c(1, 2, 3) |> sapply(\(x) 2 * x)
mrbrich
  • 853
  • 1
  • 8
  • 9