Chaining computations can sometimes be awkward.

When you have quite a number of steps, each requiring the output of the previous step, the code can become hard to read.

list(map(
  lambda x: x * 2,
  filter(
    lambda x: x % 2 == 0,
    range(10, 20)
  )
))

This Python code will produce the following list:

[20, 24, 28, 32, 36]

Elixir, F#, R (and probably many other languages) all have a solution for this: the pipeline operator.

A pipeline will transform some data by applying sequentially computations, each depending on the result of the previous one, and producing an output that will be forwarded to the next.

If python had a pipeline operator (|> for example), the previous code could be rewritten as:

range(10, 20)
  |> filter(lambda x: x % 2 == 0)
  |> map(lambda x: x * 2)
  |> list()

Which is definitely clearer.

Here is how it works in the following languages:

LanguageOperator SyntaxDescription
Elixirval |> func()Injects the lefthand-side value as first argument of the righthand-side function call
F#val |> func or func <| valInjects the value on one side to the function call on the opposite side
Rval %>% funcInjects the lefthand-side value as first argument of the righthand-side function call

In Letlang, the pipeline operator mimics the one from Elixir:

x |> add(5) |> mul(2)
# equivalent to
mul(add(x, 5), 2)