The State of Piping in JavaScript
By: Christofer Eliasson
Tags: JavaScript, React, Functional Programming, Nodejs, Programming

The Pipeline Operator Proposal

To better support chained function calls in a readable and functional manner, there is an open TC39 proposal to introduce a pipeline operator. The pipeline operator |> is inspired by equivalent operators in functional languages like F# and Elixir and also regular Unix pipes.

Using the proposed pipeline operator, we could fix the readability issue of our previous example:

Much better — now we have our reusable components, and we can compose them in a readable manner from left to right (or top to bottom, as in the above example).

This was a very basic example using a single argument for each function. Let’s look at another example with multiple arguments.

This is not too bad. Our example using the pipeline operator is more readable than the equivalent example at the last line without the pipeline operator. Still, the arrow functions necessary to handle multiple arguments in the pipeline add noise and make the code more difficult to read.

To solve the readability issue, we turn to yet another TC39 proposal — namely, the partial application proposal. In programming, partial application is the act of pinning a number of arguments to a function, producing another function with fewer arguments. According to the proposal:

This proposal introduces a new syntax using the ? token in an argument list which allows you to partially apply an argument list to a call expression by acting as a placeholder for an argument.

Using the partial application syntax, we could improve the readability of our multi-argument pipeline like this:

That is satisfying — removing the arrow functions greatly improved the readability of our example. Now the multi-argument pipeline reads almost as easily as our single argument pipeline.

This all looks very promising, but you might think, what’s the catch? Well, as it turns out there are a few, unfortunately.

First of all, the proposals for both the pipeline operator and partial application are still at Stage 1, which by the TC39 process means, “The committee expects to devote time to examining the problem space, solutions and cross-cutting concerns.” At this stage, there is no guarantee whatsoever that the proposal will ever reach the standard.

Further, for the pipeline operator, there are currently two competing proposals — F# Pipelines and Smart Pipelines. This article will not cover the details of how the two proposals differ. Both proposals share some basic commonalities like using the |> as the pipeline operator. They also overlap on how to handle the most basic use case of synchronous unary functions, like our first example with functions taking a single argument. However, the proposals do differ on many things, like how to handle asynchronous functions, partial application, etc.

Looking at the proposals, they have been around for almost three years without reaching Stage 2. One of the problems is that the committee hasn’t been able to agree on what proposal to move forward with. There is a long-running discussion on GitHub on the idea of moving forward with a minimal proposal, but unfortunately, that too seems to be stuck for now.

The standards committee operates by consensus, which is reasonable considering the impact decisions have on the language. As one TC39 committee member puts it on GitHub:

Our style in TC39 tends to be a bit more conservative, where we try to hold off until a feature is “done.”

The flip-side of this is that proposals (like the pipeline operator) risk getting stuck when the committee fails to reach a consensus on how to move forward.

Personally, I hope that the committee can agree on going forward with a minimum proposal to get the ball rolling. The minimum proposal would be a great contribution to the language on its own, and having something to build on with future proposals could hopefully aid in moving the development of the feature forward.