Apr 25, 2016
Table of contents:
In last week’s tutorial we looked at defining functions and modules.
Elixir is a functional programming language and so defining small and concise functions is a big part of the philosophy of the language.
A function should have a single concern, and so testing functions becomes really easy. In functional languages, you will often want to combine functions by passing the result of one function as the argument to the next.
If you are familiar with Unix Pipes, this is basically the exact same thing.
Elixir has a special Pipe operator for doing just this. In today’s tutorial we will be looking at the Pipe Operator in Elixir.
Before we look at the Pipe Operator, first lets try to understand why this is a problem in the first place.
An important characteristic of a functional programming language is small and concise functions. When you pass a piece of data into a function, the function will act on it and return a new piece of data.
For example, if I want to capitalise a string, I would pass it to the
capitalize function on the
String module, like this:
But what if I also need to reverse the string as well? To do this I would need to pass the return value of the
capitalize function to the
And what if I also need to split the string at the letter “l”? Well I would need to pass the return value from the
reverse function into the
So as you can probably see, this is getting kinda difficult to read.
In order to figure out what’s going on, you need to find the first function, and then work your way back out.
What’s more, when a function such as
split has a second argument, you need to figure out what the argument is by looking at the other side of the line.
And this is not even a particularly complicated example, image if we had even more transformations! This line of code would be very difficult to understand at first glance.
This is where the Pipe Operator comes in.
The Pipe operator allows you to pass the return value from one function as the first argument to the second function.
The code from above can be re-written like this using the Pipe Operator:
String.capitalize("Philip") |> String.reverse() |> String.split("l")
So as you can see, this is much easier to read because it naturally flows from left to right. This makes it much easier to understand the data transformations that are taking place.
You will also notice that you don’t need to pass the result from the previous function the next function. This makes the call to
String.reverse very clean and simple.
And when you require a second argument, such as the call to
String.split, you can simple pass the remaining arguments and the result from the previous function will automatically be used as the first argument.
This makes it really easy to see the arguments of each function without having to read both sides of the line of code at the same time.
When working with source files you can also move each stage onto a new line:
This makes reading the transformation even easier as you can just read it as a list of transformations.
However, you can only do this in source files. If you tried to do this in
iex it wouldn’t work because the first line is a complete expression.
The Pipe Operator is a really beautiful part of the Elixir language as it means you don’t have to write a mess of nested functions, or save each return value to a local variable just to pass it to the next function.
As an Elixir programmer you will see the Pipe Operator being used a lot. It’s much better to write really small, and easy to understand functions, and then compose them together.