September 22nd, 2025
One of the first game-changing features people learn about in functional programming is the pipe operator, which allows us to pass and transform data fluently through a pipeline.
In Elixir, the |>
operator simply takes the result of an expression on the left side, and passes it as the first argument to the next function on the right side:
names |> Enum.sort() |> Enum.uniq()
This is essentially equivalent to passing the output of sort()
directly into uniq()
:
Enum.uniq(Enum.sort(names))
The most obvious benefit of the pipeline is that it restructures nested funtions from an inside-out to a much more readable left-to-right, or even top-to-bottom fashion:
title
|> String.trim()
|> String.downcase()
|> String.replace(" ", "-")
It also eliminates the need for creating temporary variables, and helps with debugging and refactoring, etc.
If you're coming from Laravel, you're probably familiar with Laravel's fluent collection and string helpers:
str($title)
->trim()
->lower()
->replace(" ", "-")
->toString();
On the surface, this looks nearly the same as my Elixir example above, but it's actually much more complex under the hood:
str()
creates an Illuminate\Support\Stringable
instance, with the primitive stored on the object.Stringable
class, like trim()
, lower()
, and replace()
.$this
under the hood.Stringable
instance, so we need to cast the output to string, or call ->toString()
to get a primitive string as a result.If you've ever tried to built your own fluent API in an object-oriented language like PHP, these concepts will be familiar to you:
$this
from every method.In Elixir, functional pipelines are much simpler, because the |>
operator is implemented at the language level, and it works on any function.
There is no state to manage, the raw output is passed through each step of the pipeline, and no special getter is needed to cast the final result. In fact, you can even pipe functions across modules!
csv
|> String.split(",")
|> Enum.map(&String.trim/1)
|> Jason.encode()
This little functional |>
operator is quite the paradigm shift coming from OOP, and I'm finding that it really helps to simplify and improve code readability and composability.
Interestingly, the pipe operator is coming to PHP 8.5! I have little doubt that the PHP and Laravel communities will be all over it!
—Thanks for reading!
For updates, follow me on Twitter / X or subscribe via RSS.
© Jesse Leite