Clojure Journey II – Chose a editor

My second step through my journey to learn Clojure is to setup my text editor or IDE. I’m not a evangelist of any text editor or IDE, so I started to search for what people usually use or is best to use while coding Clojure. After few minutes and several posts around the internet, I noticed the four most indicated tools:

I started to try each one.. First I removed Cursive + IntelliJ from my options because cursive is a paid plugin, and I didn’t tried it at all. Then I tried to install Nightcode, it looks amazing, but I don’t like to use IDEs, is my personal option and in a few cases I chose to use IDEs (Java and Go).

Update: @tanrax made a great comment in this post saying that Cursive plugin is free for open source contributors and students, if you’re one, check it!

Now I have two rivals text editors and I need to chose one. I started to take a look at fireplace plugin to vim, because I use my neovim on 80% of my hours of coding, but after installed it, I faced problems when trying to fix them.

Finally I decided to take a look at Emacs (Yes, it was my last option), I never tried it before because it looks scary at the first time. I’m learning a new language, why don’t learn a new editor? I give a chance to emacs and…. It looks amazing!

In this post I’ll describe my setup and how to use emacs to development with Clojure.

Emacs or Spacemacs?

If you already use emacs and have your custom setup you can skip this part aand use your setup.

But what about those who don’t use emacs?

Emacs or Spacemacs is a long discussion, and I don’t want to get on one side now. Simplifying, spacemacs is a “comunity-driven emacs” and it comes with a lot of configuration already made. If you chose to proceed with emacs you’ll spend a time searching for plugins and custom setups that are already done or easy done with space.

As I am a beginner user with emacs, I decided to proceed with spacemacs.

Installing Emacs

Before install spacemacs, first we need emacs installed.

To install emacs is very simple and they have a nice webpage with all the links needed. As a GNU/Linux user I just downloaded the tarball file of version 27.1, extracted it and compiled/installed it from the source using the traditional ./configure, make and make install. After this emacs is installed!

$ emacs --version
GNU Emacs 27.1
Copyright (C) 2020 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file 
named COPYING.

If you have any trouble, you can see the INSTALL file that come with.

Installing spacemacs

Spacemacs have a beautiful website that need to be checked, but it has a nice README on github too.

As the date of this post, install spacemacs is very easy, just clone it in the correct directory:

git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d

After this if you start your emacs, it should open spacemacs, and it will start to self setup. It will ask you some questions, but I chose the default one for every question, and selected the vim mode, to use vim bindings inside emacs. It helped me a lot, because I’m used to use vim.

Custom setup

Now you have a file named .spacemacs on your user directory, and this file is your configuration file, similar to other text editors.

The first thing that I noticed when I started it for the first time was the size of the font, it looks very small on my monitor. To change this is easy, open your .spacemacs file (Using your spacemacs, right?), and change your size:

dotspacemacs-default-font '("Source Code Pro"
                               :size 19
                               :weight normal
                               :width normal
                               :powerline-scale 1.1)

After this next time that you open spacemacs, your text size will be better.

Other thing that I missed from vim/nvim was the famous NERDTree plugin that is a file system explorer. Fortunately I found a layer named Neotree that is basically the same thing.

To install it is simple, as the documentation says, just add the layer name neotree to the dotspacemacs-configuration-layers list.

dotspacemacs-configuration-layers
   '(
     helm
     emacs-lisp
     neotree
     )

And if you want to open the tree pressing one ke, you can paste the fallowing code inside your config file:

(global-set-key [f8] 'neotree-toggle)

And if you like to have a system explorer looking like the vim’s one, just put this in your config file:

(setq neo-theme 'nerd)

And not, just reload your emacs:

The the only thing missing in our editor now is the Clojure support, and to install it is simple, just go to the same place where you installed the neotree layer, and write “clojure”, re-open your editor, and it’s done! The Clojure support for emacs is amazing and we’lll see in the next post!

What is spacemacs layers?

The first thing to clarify is that layers is a concept from spacemacs and not from emacs.

A layer can be defined as a collection of packages and it’s configuration required to make them work well with spacemacs and each other. You can easily find a open-source layer for almost everything that you’ll need (almost), but of course, you can make private layers too.

To install a layer is easy, just follow the same steps of this post: Add its name to dotspacemacs-configuration-layers list. You can check it’s documentation to learn how to use them.

Conclusions

In this post I chose my text editor that I’ll use when coding Clojure. On the next post we’ll talk about CIDER, The Clojure Interactive Development Environment for Emacs! And spoiler: It’s amazing.

Final thought

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares@gmail.com), pm me on my Twitter or comment on this post!

Clojure Journey I – First Steps

This week I started my journey through learning Clojure. Sometime ago I’ve a brief view of LISP when I read the land of lisp book, I was very interesting, for me it’s a language with a simple concept, that on the first view looks ugly and hard, but when you understand more it’ts fabulous and genius.

Clojure is a LISP dialect hosted on JVM created by Rich Hickey It first version was published in 2005 and today it’s not one of the most popular languages, but it have a nice and great community around, working on tools, library and documentation.

If you want to learn more about Clojure and its design decisions, Rich Hickey wrote a nice (and long) paper, about its features, design decisions and history, just click here.

My first steps was to chose a book to start learning, after a few search on google, I decided to follow the famous book Clojure for the Brave and True it looks a nice book and it’s free, if I like it I can buy a physical copy to reward the author.

As my second step I like to get involved with the community, I started to follow the Clojure subreddit /r/Clojure, and the newsletter listed here.

As my next step I’ll setup my code editor, but this is the subject of the next post.

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares@gmail.com), pm me on my Twitter or comment on this post!

Follow my blog to get notified off every new post:

Elixir notes II – Anonymous Functions

Elixir is a functional language, and as the name says “functional”, one of the core parts of the language is its functions. All projects written in elixir are composed of tons of functions chained, and know how to deal with functions is a core part of every elixir programmer. On these notes let’s travel on a journey across all the ways to handle functions in elixir code.

In the first steps after writing our first “hello world” we usually learn about functions and its important mission of making a big sausage code divided into small pieces of meaningful code, that can be reused later, making our software more readable and less complex.

I think every programmer knows what its functions and how to use it in our code, but functions in the elixir can be a little bit different from those coming from some languages, especially object-oriented language that deals with mutating objects.

Most functions in elixir are what we call “pure functions”, it means that our functions will always have the same output for a given input and that it won’t generate effects that are not the value that it returns it is possible because in elixir everything is immutable by default. With pure functions, an elixir codebase is far simplest and maintainable, especially because functions usually don’t produce side effects, tests also are simple to develop too.

As I said most of the elixir function is pure functions and that’s awesome, but… A small part of functions has joined the dark side and became an impure function, and its return is not predictable, we’ll talk about it at the end of this text.

If you haven’t read yet, here is the previous posts of this series:

Anonymous Functions

To start our journey, let’s talk about anonymous functions the most basic way to create a function in elixir, create it is easy, you just need to use the fn keyword, followed by the function parameters and the body, ending with the end keyword.

For example, let’s build a function that sum 42 for the given number:

fn (number) -> number + 42 end

But you may be wondering “How do I call this function?”, as the name says anonymous function doesn’t have a name (isn’t bound to an identifier), and if we want to call it, first we need to store it on any variable.

sum = fn (number) -> number + 42 end

Depending of the other languages that you know, probably it’s new for you, but it’s very common to find in any functional language or languages that implements some functional features, usually with lambda keyword.

This example shows an important thing of Elixir, functions are first-class citizens, it basically means that functions are like other types in Elixir, and can be assigned to variables, pass as a parameter and much more. (It’s an important concept that comes from lambda calculus)

Backing to action, know we have our function assigned to sum variable, how do we call it? Simple:

sum.(2)
=> 44

In Elixir every function will return something and will be the value evaluated at the last line of the function.

A lot of functions in Elixir requires that you pass a function as a parameter, one of the most famous examples is the Enum.map/2, it receives an enumerable as the first param, and a function to be applied to each element as the second parameter, to use it, we use anonymous functions. (Functions that accept other functions as arguments are called “High Order Functions” and it’s very common in Elixir).

Enum.map([1, 2, 3, 4, 5], fn (number) -> 42 * number end)
[42, 84, 126, 168, 210]

If you want, Elixir provides a short way to create anonymous functions too, just use the & operator:

iex > hello = &(&1 + 42)
#Function<7.126501267/1 in :erl_eval.expr/5>
iex > hello.(12)
54

Your functions parameters will be available at &1, &2, &3 and so on…

Like with named functions, with anonymous functions we can do pattern matching at parameters too:

iex > hello = fn                               
... >   {:ok, name} -> "Hello #{name}"
... >   {_, message} -> "An error occured: #{error}"      
... > end                                    
#Function<7.126501267/1 in :erl_eval.expr/5>

And call this function passing the matching pattern:

iex > hello.({:ok, "Otavio"})
"Hello Otavio"
iex > hello.({:error, "Unexpected name"})
"An error occurerd: Unexpected name"

I have a great post about pattern matching too, just click here.

Interesting Point: Closures

Closures are how we call anonymous functions that contain a reference to variables outside of its scope, for example:

iex > name = "Otavio"
"Otavio"
iex > hello = fn -> IO.puts "Hello #{name}" end
#Function<21.126501267/0 in :erl_eval.expr/5>
iex > hello.()
Hello Otavio

But what will happen if we change the value of name and call it again?

...

iex > name = "Gabriela"
"Gabriela"
iex > hello.()         
Hello Otavio

This happens because Elixir holds the address of all out of the scope variables with the anonymous functions, and in this language data is immutable, so, it holds always the original value of name.

This behavior avoids side effects, and each call for our anonymous functions will produce the same result and bring to us the awesome pure functions that I talked about in the introduction.

Impure Functions

We’re not in the wonderland and some functions are not pure functions, a small part has joined the dark side and became impure functions, they are functions that the result is not always the same for a given parameter, they vary the result or produce side effects.

We have a few common examples in the programmer’s everyday life, external API calls, databases, and get user input.

iex > IO.gets "How much is 1 + 1?"
How much is 1 + 1?4
"4\n"
iex > IO.gets "How much is 1 + 1?"
How much is 1 + 1?2
"2\n"

In the previous example, the result of the function what different and its arguments was the same, this is a famous case of impure functions, but how to deal with them?

We can’t avoid this kind of function, the world is exact! But we have a lot of ways to deal with them and prevent unexpected results, but this is not in the scope of this post.

For now, focus on know that Elixir forces you to have a lot of pure functions, because everything in Elixir is immutable, but we’ll have contact if impure functions too, nothing is 100% perfect.

Conclusions

Functions are the core of every functional language (as the name says) and can help you making your code more readable and simple!

In this post, we learned about anonymous functions that will be used a lot in the future when dealing with topics like async tasks. Core Elixir’s concepts like immutable data and pure functions were studied too, and we learned about the existence of the dark side of the functions… impure functions.

Final thought

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares@gmail.com), pm me on my Twitter or comment on this post!

Follow my blog to get notified off every new post:

Elixir notes Appendix – IEx

Background art by Dmitry Burmak

When you start to use Elixir, one of the first thing that you use or see people using is IEx, let’s understand its main features and how it can help you.

IEx which stands for Interactive Elixir it’s a core part of Elixir, it can be seen as Elixir’s REPL(Read–eval–print loop) if you’re coming for other modern languages. It’s helpful when you’re developing your application, and know how to use it can save you time.

Evaluating Expressions

IEx already comes with Elixir, so, if you have elixir installed (Or inside a docker container please) you just need to type iex and you’ll enter.

Erlang/OTP 22 [erts-10.4.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]              

Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)                               
iex(1)>

At interactive mode any Elixir expression will be evaluated, for example:

iex(1)> 1 + 1
2

It sounds like ship ice to Antarctica for people coming from scripting languages with built-in REPL like Ruby or Python, but it’s worth knowing how to use IEx to be a powerful tool in your development.

It’s important to remember that any expression in IEx will be evaluated and not compiled, so, it’s not recommended to run benchmarks (or something like that) inside IEx.

Different from many similar applications IEx can’t be closed by typing ctrl + d or sending SIGINT signal (ctrl + c), if you type ctrl+c an interesting menu will be displayed:

iex(2)>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution

For now, everything that you need to know is that if you type a and press enter you’ll close IEx, but one great people make a nice shortcut: Press ctrl+c two times and you’ll close it too.

Multi Line

It suports multi line expressions too:

iex(1)> fn (a, b) ->
...(1)> a + b
...(1)> end
#Function<13.91303403/2 in :erl_eval.expr/5>

If you want to copy and paste a multi line valid expression:

[1, [2], 3]
|> List.flatten()

Sometimes it won’t work, for example:

iex(1)> [1, [2], 3]
[1, [2], 3]
iex(2)> |> List.flatten()
** (SyntaxError) iex:2: syntax error before: '|>'

In these cases a nice tip is to place your multi line expression inside parentheses.

iex(2)> (
...(2)> [1, [2], 3]
...(2)> |> List.flatten()
...(2)> )
[1, 2, 3]

If you get stuck into a multi-line statement and doesn’t know how to get out of this, is just type #iex:break:

iex(3)> ["12
...(3)> c"
...(3)> 3 + 3
...(3)> 2 / 3
...(3)> \
...(3)> "
...(3)> ]
...(3)>
...(3)>
...(3)>
...(3)> #iex:break
** (TokenMissingError) iex:3: incomplete expression

Autocomplete

IEx comes with autocomplete too, and it works very fast, just type tab and it will show your options.

iex(1)> List.
Chars                 ascii_printable?/1    ascii_printable?/2
delete/2              delete_at/2           duplicate/2
first/1               flatten/1             flatten/2
foldl/3               foldr/3               improper?/1
insert_at/3           keydelete/3           keyfind/3
keyfind/4             keymember?/3          keyreplace/4
keysort/2             keystore/4            keytake/3
last/1                myers_difference/2    myers_difference/3
pop_at/2              pop_at/3              replace_at/3
starts_with?/2        to_atom/1             to_charlist/1
to_existing_atom/1    to_float/1            to_integer/1
to_integer/2          to_string/1           to_tuple/1
update_at/3           wrap/1                zip/1

iex(1)> List.

And if you type List.del it will complete for you offcourse, just press tab like you do on Linux.

Compiling

If you write a module:

defmodule Hello do
  def hello do
    IO.puts "Hello World"
  end
end

You can compile it inside your IEx, and then, use it.

iex(1)> c "test.ex"
[Hello]
iex(2)> Hello.hello
Hello World
:ok

Now if you change your module message to be “Hello Universe”, it won’t reload your module automatically, you need to recompile it using r/1 or compiling it again with c/1:

iex(4)> r Hello
warning: redefining module Hello (current version defined in memory)
  test.ex:1

{:reloaded, Hello, [Hello]}
iex(5)> Hello.hello
Hello Universe
:ok

A important thing to know is that if your file its a interpreted file of type exs, it will not be compiled and just interpreted.

Getting Past Expressions

It’s common to have a way to get the value of the past expressions, IEx you just need to use v:

iex(8)> 3 + 3
6
iex(9)> v
6

Shell history and history search

I love to use terminals, and I love to search throughout the history for a command that I made last year just typing Ctrl + r, inside IEx it’s possible to do the same just typing Ctrl + r too:

iex(1)> 1 + 2
3
iex(2)> 11 + 3
14
iex(3)> 1 + 3
4
(search)`11': 11 + 3

IEx doesn’t preserve your shell history if you close your session, but you can keep it by just setting one env var, can you imagine doing history search across all command that you ever typed?

export ERL_AFLAGS="-kernel shell_history enabled"

If you want to configure something about IEx, you can use configure/1, it has a lot of options of customization like colors, and you can setup things like history size too, I recommend you read about it here.

Debugging

One of the most loved thing to any developer it’s a debugger, with debugger you can develop more easily, find bugs and much more. Elixir happily has its debugger too, and to use it’s very simple, just paste require IEx; IEx.pry where you want that your application stop, let’s see an example with our Hello module, to see it working let’s add our message to one variable:

defmodule Hello do
  def hello do
    message = "Hello World"
    require IEx; IEx.pry
    IO.puts message
  end
end

After this, just call hello method inside our iex:

iex(1)> c "test.ex"
[Hello]
iex(2)> Hello.hello
Break reached: Hello.hello/0 (test.ex:4)

    2:   def hello do
    3:     message = "Hello World"
    4:     require IEx; IEx.pry
    5:     IO.puts message
    6:   end

pry(1)> message
"Hello World"
pry(2)> continue
Hello World
:ok

Elixir has many ways to debug your applications, this one is the simplest along with IO.inspect, and can be very helpful when you’re starting to study Elixir or dealing with simple bugs inside your app.

Displaying Help and Information

If you want to read docs about some module you just need to use helper h/1, it will display all the documentation shipped with the module like h Map, you can use the same helper to know about one method, for example h Map.keys (I’ll not paste here the output because its too long).

If you want to get information about any Elixir term, just use the i/1, example:

iex(7)> i Map
Term
  Map
Data type
  Atom

... ... 

You can get information about types defined inside module to:

iex(1)> t(Enum)
@type default() :: any()

@type index() :: integer()

@type element() :: any()

@type acc() :: any()

@type t() :: Enumerable.t()

Conclusions

IEx can help you when studying or developing Elixir, it has many beautiful features, in this post I don’t cover everyone but the principal ones, I think that all you need to start developing Elixir is here. In future posts I can return to IEx to talk about otherr features like connecting in remote nodes.

Final thought

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares@gmail.com), pm me on my Twitter or comment on this post!

Follow my blog to get notified off every new post:

Elixir Notes I – Pattern Matching

Background art by Dmitry Burmak

When you came across Elixir, one of the first things that you’ll hear about is the famous “Pattern Matching” and Elixir’s match operator, this is not a coincidence since many things in Elixir/Erlang are built around it.

No wonder, a lot of courses and books explain pattern matching in the first chapters, “Programming Elixir” by Dave Thomas is probably the most famous book reference and explains it in the first few chapters, I recommend it. In this post I’ll explain what pattern matching is based on what I studied in recent months, I hope I can explain clearly.

Understanding it

When you learn your first programming language(in most cases), you learn to use the equal sign in another way, different from what you learned at your school when younger.

You learn that you use an equal sign to assign values to variables:

irb(main):001:0> number = 10
=> 10

Ok, Elixir can make variable assignment like that:

iex(1)> x = 1
1

But the main difference behind Elixir equal sign is on the next example:

iex(1)> x = 1
1
iex(2)> x = 2
2
iex(3)> 2 = x
2
iex(4)> 3 = x
** (MatchError) no match of right hand side value: 2

Did you realize something strange here? Let’s try the same in Ruby.

irb(main):001:0> x = 1
=> 1
irb(main):002:0> x = 2
=> 2
irb(main):003:0> 2 = x
SyntaxError ((irb):3: syntax error, unexpected '=', expecting end-of-input)
2 = x
  ^

It occurs because Elixir doesn’t assign values to a variable using equal sign like other languages, its equal sign is more like what you learned in algebra, from the definition:

“Shows that what is on the left of the sign is equal in value or amount to what is on the right of the sign.”

Equal sign Elixir

When we typed 2 = x for elixir is like as we typed 2 = 2, it’s true, so it evaluated 2. In ruby and most imperative languages, it tries to assign value 2 two Integer 2, so it fails. At the next line of our Elixir example, we tried to 3 = x and it raised MatchError telling that it can’t match 3 to 2, and that’s true.

Let’s summarize the algorithm at this point:

Elixir tries to check if both values are equal, if true, it’s a valid expression if not, it raises a MatchError, but if we have a variable on the left side it will match everything biding the value of the right side on the left side.

Ok, at this time you may be thinking “Ok, it’s different from the most common equal sign in programming, but it can’t change my daily work”, keep calm and let’s study more complex uses of it.

We already learned the concept of matching, but when the “pattern” goes on? We can use patterns to make more complex matches between the left and right side of equal, let’s see some examples to get started.

iex(1)> [a, b, c] = [1, 2, 3]
[1, 2, 3]
iex(2)> a
1
iex(3)> b
2
iex(4)> c
3

The language always will try to make the right side equal to the left side, on the previous example, it sees a list [1, 2, 3] on the right side and another of [a, b, c] on the right side, to make both equal it just need to bind the values of right side into the left side.

Elixir always will try to equalize both sides, based on its patterns.

iex(1)> [a, b, [c, d]] = [1, 2, [20, [30, 40]]]
[1, 2, [20, [30, 40]]]
iex(2)> a
1
iex(3)> b
2
iex(4)> c
20
iex(5)> d
[30, 40]
Elixir complex pattern matching

This process of treat equals sign as an assertion of equivalence and bind values of the right side into left side variables based on patterns is called pattern matching.

Elixir provides two useful operators to help us with pattern matching, one of these is the underscore operator, you can use it when you don’t want to assign a value during pattern matching, and it will ignore any value that is assigned and will help your code be more readable, every time that someone looks at these, will know that the code doesn’t care about what is assigned to underscore.

iex(1)> [a, _] = [1, 2]
[1, 2]
iex(2)> a
1
iex(3)> _
** (CompileError) iex:4: invalid use of _. "_" represents a value to be ignored in a pattern and cannot be used in expressions

Lists have a problem that we don’t know previously its size, if we have a function that can return lists of differents size pattern matching will be hard, we don’t know how to match it on the left side. Fortunately, Elixir provides us an option to match against the head and tail of the list and it is the other operator that can help us with pattern matching.

iex(4)> [head | tail] = [10, 20, 30, 40, 50]
[10, 20, 30, 40, 50]
iex(5)> head
10
iex(6)> tail
[20, 30, 40, 50]

Elixir always will assign list’ head to the variable on the left side of the pipe, and the rest (also known as tail) to the variable on the right side of the pipe.

Elixir pipe operator separating head and tail from list

Function Responses

Follow my blog to get notified off every new post:

Pattern matching is also useful to check the return of functions, but how it works? In Elixir is very common to functions return what we call “tagged tuples”, that’s nothing more than a tuple with the first item being an atom describing functions return status. The pattern is simple when the function was successful, its returns {:ok, response} and when an error occurred {:error, response}.

As our example, let’s analyze the responses of Poison, the most popular Elixir JSON library.

iex(10)> Poison.Parser.parse(~s({"name": "Otavio Valadares", "age": 22}), %{})
{:ok, %{"age" => 22, "name" => "Otavio Valadares"}}
iex(11)> Poison.Parser.parse(~s({"name": "Otavio Valadares", "age": }), %{})
{:error, {:invalid, "}", 36}}

This convention, allow us to make pattern matching against function returns, we can match against :ok and :error tags.

defmodule Example do
  def parse(json) do
    case Poison.Parser.parse(json) do
      {:ok, result} ->
        IO.inspect(result)
      {:error, error} ->
        IO.inspect(error)
      _ ->
        "Unexpected Error"
    end
  end
end

Example.parse("{\"name\": \"Otavio Valadares\", \"age\": 22}")
# => %{"age" => 22, "name" => "Otavio Valadares"}

Example.parse("{\"name\": \"Otavio Valadares\", \"age\":}")
# => {:invalid, "}", 35}

At this example, we use pattern matching on the case statement based on Poison.Parser.parse the response, when it returns a tuple with the first atom :ok we bind the response (second element) to result in variable and prints it, and we do the same when it responds with:error tuple.

Pattern matching against function result

Most libraries in Elixir follow this pattern on responses, so get used to working with it. The previous example shows just one of several ways that we can handle it, and obviously, it’s not the best solution, but a good way to beginners get started.

Multi-Clause Functions

We learned the basics of pattern matching and now it’s time to talk about the icing on the cake, Elixir’s pattern match can also control our software flow, choosing what function calls based on args and arity, this is the craziest thing that pattern matching can give to us.

If we declare two functions and send a message, we can choose the function that will be called.

Suppose that we have a module called Geometry that will calculate the area of different shapes, disregarding object oriented programming, what would you consider doing? I think the most common solution will create a function that receives an argument that is the shape to be calculated, and its numbers. This solution probably will need a lot of ifs or case statement to check what shape is and do the math.

With Elixir this problem has a different and cleaner way to be solved using what is called “Multi-clause Functions”, we can define multiple functions with the same name but each one with a different function clauses, Elixir will try each clause until it finds one that matches (using pattern matching).

Let’s begin with our example:

defmodule Geometry do
  def area({:square, a}) when is_number(a) do
    {:ok, a * a}
  end

  def area({:circle, r}) when is_number(r) do
    {:ok, r * :math.pi}
  end
end

We defined our module Geometry and inside it defined two functions, we have both functions named area but one receiving a tuple with {:square, a} and other one expecting {:circle, r}. Let’s try to use our module:

IO.inspect Geometry.area({:square, 10})
# => {:ok, 100}
IO.inspect Geometry.area({:circle, 5})
# => {:ok, 15.707963267948966}

Elixir will choose which function execute based on what was sent to function, it will try to pattern match against each one if it successfully matched, this function will be executed.

Function pattern matching

And of course, if we call passing a function clause that no one functions handle, it will raise a FunctionClauseError error:

IO.inspect Geometry.area({:rectangle, 4, 8})
# (FunctionClauseError) no function clause matching in Geometry.area/1

To avoid this kind of error, we can define a function that handles everything to returns error when something unexpected was sent, but it’s important to note that function needs to be placed at the end of the module because Elixir will execute the first function that matches against.

def area(unknown) do
  {:error, {:unknown_shape, unknown}}
end

Multi-clause functions with pattern matching are another tool that elixir brings to us that can be used to control our software flow, it is powerful when understood can be easily used to solve a variety of problems.

Conclusions

As we saw in this post, pattern matching is powerful and lives in Elixir soul, it’s impossible to look at any project and don’t see pattern matching being used everywhere, you can use pattern matching to unpack any data structure and control your software flow, that’s why pattern matching matters. What we saw in this post was an introduction necessary to get started in my opinion.

Final thought

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares@gmail.com), pm me on my Twitter or comment on this post!

Follow my blog to get notified off every new post:

Reference