Solvedjulia Proposal: Deprecate then remove function piping

Proposal

Deprecate the current use of |> as a function pipe. That is, the syntax x |> f would be deprecated in favor of the normal call syntax f(x). After the deprecation period, Base.:(|>) would be undefined.

This change was initially suggested by tkelman in #16985 (comment).

There has been a lot of contentious debate over various syntaxes for function piping (in particular, see #5571), with arguments for mimicking a variety of languages. That discussion has been had ad nauseum and I do not wish to rehash it. That is NOT the purpose of this proposal.

Rationale

A number of well thought out, well maintained packages have implemented macros that provide convenient piping syntax for a variety of use cases, both general and specific. Examples include Lazy.jl, FunctionalData.jl, Pipe.jl, and ChainMap.jl, among others.

StefanKarpinski and andyferris gave us arbitrary function composition in #17155, which can serve a similar purpose in many situations.

As tkelman similarly argued in #5571, the function pipeline in Base is backwards from the familiar call syntax; having both in the Base language is essentially endorsing the use of 2 disparate syntaxes to achieve the same goal. While there are often multiple ways to write the same thing using solutions in Base, typically the solutions at least adhere to a similar mental model. In this case, the syntaxes employ literally opposite mental models.

Function pipelines violate the principle of least surprise by applying the action after the object. That is, if you read sum(x) you know immediately when you see sum() that you're going to add up the values in the argument. When you see x |> sum, you see x, then all of a sudden you're adding up its values. Few if any other Base solutions put the action at the end, which makes piping the odd one out.

Piping does indeed have precedent in other languages, e.g. Hadley Wickham's %>% in R (which is not part of base R), and sometimes that style/flow makes sense. However, in the interest of consistency within Base Julia, I propose that we defer the responsibility for providing piping syntax to packages, which can redefine |> or provide convenience macros as they see fit.

Action Items

Should this proposal be accepted, the action items would be:

  • Remove uses of the syntax within Base, if any exist
  • Provide a formal deprecation for Base.:(|>) in either 0.6 or 1.0
  • Remove it in a subsequent release
38 Answers

✔️Accepted Answer

If we're deprecating this should we also deprecate * for string concatenation? That has similar issues as it's with redundant with string(a, b), and violates the principle of least surprise given that a and b aren't numbers.

More generally, we should probably deprecate all infix notation, as it's confusing to have multiple calling conventions like *(a, b) vs a * b – we can trim our current 3 disparate syntaxes down to one and get total consistency. To avoid ugliness we might consider moving the function call inside the parens, and perhaps getting rid of the redundant commas, as well.

Other Answers:

We could add the functionality of Pipe.jl to the language, and then you'd have it without needing to write @pipe.

The main reason to deprecate |> would be if we want to reclaim the syntax for some other purpose that people like much better.

I know this issue is closed. Just wanted to say "thank you" for keeping the operator.

Function piping provides a postfix syntax for function calling, which is convenient at the REPL for interactive data generation and further visualization/summarization.

A use case that I have seen many people type is

julia> somecomplicatedthingproducingarray
...

<ARROW UP>

julia> somecomplicatedthingproducingarray |> summarize

where the summarize function is something like a plot or histogram

I'm kind of neutral on this one, but I will second the sentiment that |> being backwards from normal function call syntax is the whole point of it. Even the biggest fans of piping are not asking (AFAIK) for e.g. sin <| x because that really is redundant with sin(x). |> is for those cases where it's easier on the eyes and/or brain to think of data flowing left to right without lots of parentheses.

More Issues: