May 02, 2016
Table of contents:
A couple of weeks ago we looked at defining functions and modules in Elixir (Working with Functions and Modules in Elixir).
An important concept that we didn’t look at in that tutorial was function arity.
Unless you come from a Computer Science background, you have probably never come across the term “function arity”. It basically means, the number of arguments that a function takes.
In Elixir, you can define multiple functions with the same name in the same Module as long as they have a different arity. This is because Elixir will treat them as different functions.
In today’s tutorial we are going to be looking at the importance of function arity in Elixir.
The term arity is a fancy way of saying the number of arguments a function accepts. For example, we can check to see if a string is a binary with the following function:
is_binary("Hello World")
This function accepts one argument and so we say that it has an arity of 1.
If you read through the Elixir documentation you might see this function written as is_binary/1
where /1
indicates it’s arity.
So now that you know what function arity means, why is this important in Elixir? In Elixir, functions in the same Module can have the same name, but with different arity.
For example we can split a string by it’s white space:
String.split("Hello World")
If you were writing about this function, you would write String.split/1
Alternatively you can pass a value to split on:
String.split("Hello,World", ",")
This function would be known as String.split/2
because it takes two arguments.
These two functions, despite having the same name, are actually two different functions because they have a different arity.
So hopefully you can see that the number of arguments that a function accepts defines the function itself.
So why is function arity important? It would be pretty confusing if you had two functions with the same name that did two totally different things.
In Elixir, lower arity functions typically delegate to higher arity functions by providing default arguments.
To see this in action, we can create a pseudo module for splitting strings:
defmodule MyString do
def split(string) do
split(string, " ")
end
def split(string, pattern) do
# Split the string by the pattern
end
end
The MyString.split/1
function accepts a single string
argument and then delegates to the MyString.split/2
function by passing a default pattern of a blank space.
This means you can call the MyString.split/1
function, or you can call the MyString.split/2
function and pass a pattern to split by.
Alternatively you can write the module like this:
defmodule MyString do
def split(string, pattern \\ " ") do
# Split the string by the pattern
end
end
In this example the pattern
argument has a default value of " "
. When Elixir compiles this function, it actually will create two functions as we saw in the first example.
Function arity is an important concept in Elixir, particularly when it comes to writing recursive functions. If you come from a language such as Ruby or Python, being able to have two functions with the same name could be quite confusing.
But once you start to write a lot of Elixir code, you will find that writing functions with different arity’s is actually a really cool aspect of the language.
Another important characteristic of Elixir that we haven’t covered so far is Pattern Matching.
And so, in next week’s tutorial we will look at Pattern Matching in Elixir