Erlang 3: Syntax in Functions

eric | Jan. 6, 2020, 8:45 p.m.

Comments to the book "Learn You Some Erlang For Great Good" by Fred Hébert, Chapter 3 - Syntax in Functions. Pattern matching is much easier to achieve in Erlang than in many other languages, but the syntax takes some time to get used to. Instead of if-else or similar conditional branching, in Erlang you simply use functional declarations with a pattern. Learning goals: Being able to create pattern matching, retaining unbound vs unbound variables, and how to work with guards. Challenges: Differences between unbound vs unbound variables. Fully understanding how to work with guards.

Learn You Some Erlang For Great Good by Fred HébertThis article series has come about as a result of my efforts to learn Erlang. In order to learn the language, I am reading the book "Learn You Some Erlang For Great Good" by Fred Hébert. Every time I come across something that I find difficult to understand I will make an effort to understand it and explain my understanding in detail. I will also - as far as possible - site alternative sources, possible exercises and more. First off, maybe you could be a pal and buy Fred Herbert's book. There is a huge effort behind that book and I think Fred deserves our support. You can get it at No Starch Press.

I must admit that I am cheating a bit because I read ahead quite a few chapters before rereading an earlier chapter and then commenting on that chapter on this site. This is to discover what is important to remember and / or easy to forget as I dig deeper into the content.

Each article has a list of references that I stongly suggest you have a look at, including the Erlang Language Reference, the ETS reference and Joe Armostrong's book Programming Erlang.

Pattern Matching (Again)

Video 1: Pattern matching in Erlang

Pattern matching is much easier to achieve in Erlang than in many other languages, but the syntax takes some time to get used to. Instead of if-else or similar conditional branching, in Erlang you simply use functional declarations with a pattern.

 

Function declaration in Erlang

Figure 1: Function declaration in Erlang

 

A functional declaration consists of functional clauses separated by semicolons and it is ended by a period.

Finding Stuff

The pattern in the expression can be used for more than just conditional branching. It can be used to find stuff, for instance in a list:

findhead([H|_]) -> H.

findsecond([_,S|_]) -> S.

Listing 1: Functions for finding head and second in a list.

Let's see it in practice. If we create a list containing atoms, [dolphins, krikkiters, oglaroonians, poghrils], the first expression should give us dolphins and the second krikkiters. We create a module finding_stuff and include the functions above:

-module(finding_stuff).
-compile(export_all).

findhead([H|_]) -> H.

findsecond([_,S|_]) -> S.

Listing 2: Module with functions for finding head and second in a list.

Compiling and running the code:

 

Finding stuff with Erlang pattern matching

Figure 2: Finding stuff with Erlang pattern matching

 

Comparing Stuff

If we want to compare two elements, we can use the following module:

-module(comparisons).
-compile(export_all).

same(X,X) ->
true;
same(_,_) ->
false.

Listing 3: Module with functions for comparison.

Running the code gives us:

 

Comparing stuff with Erlang pattern matching

Figure 3: Comparing stuff with Erlang pattern matching

 

It is not easy to see what is going on here. How does the expression same(X,X) really work? To understand that, we need to have a look at bound and unbound variables in Erlang.

Bound and Unbound Invariable Variables

When a variable is bound, it has a value connected to it. When a variable is unbound, no value is connected to the variable. Once bound, the value of the variable cannot be changed. The variable is immutable.

In the expression same(X,X), Erlang treats the second variable as already bound. Since both are named X, it compares the first unbound variable to the second bound variable, and will only return true when both are equal, because X cannot change value. Only if the "new" value is equal to the old one will there be a match, and the function returns true. If not, it passes on to the next pattern match, which is a catch-all, and returns false.

Still not clear? Check out Armstrong-s explanation of single assignment variables (synonym for immutable variables) in Programming Erlang, 2nd Ed., p.28.

Guards

There are limits to what you can do with pattern matching. Patterns aren't good at expressing ranges of values or types of data. This can be done with guards. A guard is simply an addition to the pattern matching, a boolean function placed after the key word, "when" and before the arrow, "->".

-module(comparisons).
time_left(Time) when Time < 3 -> "So long and thanks for all the fish".

Listing 4: Simple guard.

Calling time_left(X) with X less than 3 will give the response "So long and thanks for all the fish". You can also add statements to the guard with comma (,), semicolon (;), andalso and orelse. For instance:

time_left(Time,Race) when Time < 3, is_atom(Race) ->  "So long and thanks for all the fish".

Listing 5: Simple guard with two conditions.

What are the differences between the operators?

  • Comma, semicolon: Catch exceptions as they happen. Cannot be nested inside guards.
  • andalso, orelse: Do not catch exceptions as they happen. Can be nested inside guards.

References

Other Erlang Resources

Sites

The Erlang main site

Erlang Reference Manual User's Guide

Erldocs - An alternative to the official sites.

Erlang Patterns - A collection of Erlang patterns

Rebar3 - A build tool for Erlang that makes it easy to compile and test Erlang applications and releases.

Communities

Erlang mailing lists and forums

The Google group Erlang Programming

Erlang on Stack Exchange

Erlang on Freenode - Use #Erlang

Erlang on Slack

Books

"Learn You Some Erlang For Great Good", by Fred Hebert

"Programming Erlang", by Joe Armstrong

Articles

The Zen of Erlang, by Fred Hebert. A partly practical, partly philosophical take on Erlang.

Other

Ericsson's coding standard for Erlang - Programming rules and conventions.

Getting started with Erlang using IntelliJ IDEA (including Rebar3).

About Me

Experienced dev and PM. Data science, DataOps, Python and R. DevOps, Linux, clean code and agile. 10+ years working remotely. Polyglot. Startup experience.
LinkedIn Profile

By Me

Statistics & R - a blog about - you guessed it - statistics and the R programming language.
R-blog

Erlang Explained - a blog on the marvelllous programming language Erlang.
Erlang Explained