<?xml version="1.0" encoding="latin1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
<year>2003</year><year>2009</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
The contents of this file are subject to the Erlang Public License,
Version 1.1, (the "License"); you may not use this file except in
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
</legalnotice>
<title>Sequential Programming</title>
<prepared></prepared>
<docno></docno>
<date></date>
<rev></rev>
<file>seq_prog.xml</file>
</header>
<section>
<title>The Erlang Shell</title>
<p>Most operating systems have a command interpreter or shell, Unix
and Linux have many, Windows has the Command Prompt. Erlang has
its own shell where you can directly write bits of Erlang code
and evaluate (run) them to see what happens (see
<seealso marker="stdlib:shell">shell(3)</seealso>). Start
the Erlang shell (in Linux or UNIX) by starting a shell or
command interpreter in your operating system and typing
<c>erl</c>, you will see something like this.</p>
<pre>
% <input>erl</input>
Erlang (BEAM) emulator version 5.2 [source] [hipe]
Eshell V5.2 (abort with ^G)
1></pre>
<p>Now type in "2 + 5." as shown below.</p>
<pre>
1> <input>2 + 5.</input>
7
2></pre>
<p>In Windows, the shell is started by double-clicking on the Erlang
shell icon.</p>
<p>You'll notice that the Erlang shell has numbered the lines that
can be entered, (as 1> 2>) and that it has correctly told you
that 2 + 5 is 7! Also notice that you have to tell it you are
done entering code by finishing with a full stop "." and a
carriage return. If you make mistakes writing things in the shell,
you can delete things by using the backspace key as in most
shells. There are many more editing commands in the shell
(See the chapter <seealso marker="erts:tty">"tty - A command line interface"</seealso> in ERTS User's Guide).</p>
<p>(Note: you will find a lot of line numbers given by the shell
out of sequence in this tutorial as it was written and the code
tested in several sessions).</p>
<p>Now let's try a more complex calculation.</p>
<pre>
2> <input>(42 + 77) * 66 / 3.</input>
2618.0</pre>
<p>Here you can see the use of brackets and the multiplication
operator "*" and division operator "/", just as in normal
arithmetic (see the chapter
<seealso marker="doc/reference_manual:expressions">"Arithmetic Expressions"</seealso> in the Erlang Reference Manual).</p>
<p>To shutdown the Erlang system and the Erlang shell type
Control-C. You will see the following output:</p>
<pre>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
<input>a</input>
%</pre>
<p>Type "a" to leave the Erlang system.</p>
<p>Another way to shutdown the Erlang system is by entering
<c>halt()</c>:</p>
<pre>
3> <input>halt().</input>
% </pre>
</section>
<section>
<title>Modules and Functions</title>
<p>A programming language isn't much use if you can just run code
from the shell. So here is a small Erlang program. Enter it into
a file called <c>tut.erl</c> (the file name <c>tut.erl</c> is
important, also make sure that it is in the same directory as
the one where you started <c>erl</c>) using a suitable
text editor. If you are lucky your editor will have an Erlang
mode which will make it easier for you to enter and format your
code nicely (see the chapter
<seealso marker="tools:erlang_mode_chapter">"The Erlang mode for Emacs"</seealso> in Tools User's Guide), but you can manage
perfectly well without. Here's the code to enter:</p>
<code type="none">
-module(tut).
-export([double/1]).
double(X) ->
2 * X.</code>
<p>It's not hard to guess that this "program" doubles the value of
numbers. I'll get back to the first two lines later. Let's compile
the program. This can be done in your Erlang shell as shown below:</p>
<pre>
3> <input>c(tut).</input>
{ok,tut}</pre>
<p>The <c>{ok,tut}</c> tells you that the compilation was OK. If it
said "error" instead, you have made some mistake in the text you
entered and there will also be error messages to give you some
idea as to what has gone wrong so you can change what you have
written and try again.</p>
<p>Now lets run the program.</p>
<pre>
4> <input>tut:double(10).</input>
20</pre>
<p>As expected double of 10 is 20.</p>
<p>Now let's get back to the first two lines. Erlang programs are
written in files. Each file contains what we call an Erlang
<em>module</em>. The first line of code in the module tells us
the name of the module (see the chapter
<seealso marker="doc/reference_manual:modules">"Modules"</seealso>
in the Erlang Reference Manual).</p>
<code type="none">
-module(tut).</code>
<p>This tells us that the module is called <em>tut</em>. Note
the "." at the end of the line. The files which are used to store
the module must have the same name as the module but with
the extension ".erl". In our case the file name is <c>tut.erl</c>.
When we use a function in another module, we use the syntax,
<c>module_name:function_name(arguments)</c>. So</p>
<pre>
4> <input>tut:double(10).</input></pre>
<p>means call function <c>double</c> in module <c>tut</c> with
argument "10".</p>
<p>The second line:</p>
<code type="none">
-export([double/1]).</code>
<p>says that the module <c>tut</c> contains a function called
<c>double</c> which takes one argument (<c>X</c> in our example)
and that this function can be called from outside the module
<c>tut</c>. More about this later. Again note the "." at the end
of the line.</p>
<p>Now for a more complicated example, the factorial of a number
(e.g. factorial of 4 is 4 * 3 * 2 * 1). Enter the following code
in a file called <c>tut1.erl</c>.</p>
<code type="none">
-module(tut1).
-export([fac/1]).
fac(1) ->
1;
fac(N) ->
N * fac(N - 1).</code>
<p>Compile the file</p>
<pre>
5> <input>c(tut1).</input>
{ok,tut1}</pre>
<p>And now calculate the factorial of 4.</p>
<pre>
6> <input>tut1:fac(4).</input>
24</pre>
<p>The first part:</p>
<code type="none">
fac(1) ->
1;</code>
<p>says that the factorial of 1 is 1. Note that we end this part
with a ";" which indicates that there is more of this function to
come. The second part:</p>
<code type="none">
fac(N) ->
N * fac(N - 1).</code>
<p>says that the factorial of N is N multiplied by the factorial of
N - 1. Note that this part ends with a "." saying that there are
no more parts of this function.</p>
<p>A function can have many arguments. Let's expand the module
<c>tut1</c> with the rather stupid function to multiply two
numbers:</p>
<code type="none">
-module(tut1).
-export([fac/1, mult/2]).
fac(1) ->
1;
fac(N) ->
N * fac(N - 1).
mult(X, Y) ->
X * Y.</code>
<p>Note that we have also had to expand the <c>-export</c> line
with the information that there is another function <c>mult</c>
with two arguments.</p>
<p>Compile:</p>
<pre>
7> <input>c(tut1).</input>
{ok,tut1}</pre>
<p>and try it out:</p>
<pre>
8> <input>tut1:mult(3,4).</input>
12</pre>
<p>In the example above the numbers are integers and the arguments
in the functions in the code, <c>N</c>, <c>X</c>, <c>Y</c> are
called variables. Variables must start with a capital letter
(see the chapter
<seealso marker="doc/reference_manual:expressions">"Variables"</seealso>
in the Erlang Reference Manual). Examples of variable could be
<c>Number</c>, <c>ShoeSize</c>, <c>Age</c> etc.</p>
</section>
<section>
<title>Atoms</title>
<p>Atoms are another data type in Erlang. Atoms start with a small
letter ((see the chapter
<seealso marker="doc/reference_manual:data_types">"Atom"</seealso>
in the Erlang Reference Manual)), for example: <c>charles</c>,
<c>centimeter</c>, <c>inch</c>. Atoms are simply names, nothing
else. They are not like variables which can have a value.</p>
<p>Enter the next program (file: <c>tut2.erl</c>) which could be
useful for converting from inches to centimeters and vice versa:</p>
<code type="none">
-module(tut2).
-export([convert/2]).
convert(M, inch) ->
M / 2.54;
convert(N, centimeter) ->
N * 2.54.</code>
<p>Compile and test:</p>
<pre>
9> <input>c(tut2).</input>
{ok,tut2}
10> <input>tut2:convert(3, inch).</input>
1.1811023622047243
11> <input>tut2:convert(7, centimeter).</input>
17.78</pre>
<p>Notice that I have introduced decimals (floating point numbers)
without any explanation, but I guess you can cope with that.</p>
<p>See what happens if I enter something other than centimeter or
inch in the convert function:</p>
<pre>
12> <input>tut2:convert(3, miles).</input>
** exception error: no function clause matching tut2:convert(3,miles)</pre>
<p>The two parts of the <c>convert</c> function are called its
clauses. Here we see that "miles" is not part of either of
the clauses. The Erlang system can't <em>match</em> either of
the clauses so we get an error message <c>function_clause</c>.
The shell formats the error message nicely, but the error tuple
is saved in the shell's history list and can be output by the shell
command <c>v/1</c>:</p>
<pre>
13> <input>v(12).</input>
{'EXIT',{function_clause,[{tut2,convert,[3,miles]},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_exprs,6},
{shell,eval_loop,3}]}}</pre>
</section>
<section>
<title>Tuples</title>
<p>Now the <c>tut2</c> program is hardly good programming style.
Consider:</p>
<code type="none">
tut2:convert(3, inch).</code>
<p>Does this mean that 3 is in inches? or that 3 is in centimeters
and we want to convert it to inches? So Erlang has a way to group
things together to make things more understandable. We call these
<em>tuples</em>. Tuples are surrounded by "{" and "}".</p>
<p>So we can write <c>{inch,3}</c> to denote 3 inches and
<c>{centimeter,5}</c> to denote 5 centimeters. Now let's write a
new program which converts centimeters to inches and vice versa.
(file <c>tut3.erl</c>).</p>
<code type="none">
-module(tut3).
-export([convert_length/1]).
convert_length({centimeter, X}) ->
{inch, X / 2.54};
convert_length({inch, Y}) ->
{centimeter, Y * 2.54}.</code>
<p>Compile and test:</p>
<pre>
14> <input>c(tut3).</input>
{ok,tut3}
15> <input>tut3:convert_length({inch, 5}).</input>
{centimeter,12.7}
16> <input>tut3:convert_length(tut3:convert_length({inch, 5})).</input>
{inch,5.0}</pre>
<p>Note on line 16 we convert 5 inches to centimeters and back
again and reassuringly get back to the original value. I.e
the argument to a function can be the result of another function.
Pause for a moment and consider how line 16 (above) works.
The argument we have given the function <c>{inch,5}</c> is first
matched against the first head clause of <c>convert_length</c>
i.e. <c>convert_length({centimeter,X})</c> where it can be seen
that <c>{centimeter,X}</c> does not match <c>{inch,5}</c>
(the head is the bit before the "->"). This having failed, we try
the head of the next clause i.e. <c>convert_length({inch,Y})</c>,
this matches and <c>Y</c> get the value 5.</p>
<p>We have shown tuples with two parts above, but tuples can have
as many parts as we want and contain any valid Erlang
<em>term</em>. For example, to represent the temperature of
various cities of the world we could write</p>
<code type="none">
{moscow, {c, -10}}
{cape_town, {f, 70}}
{paris, {f, 28}}</code>
<p>Tuples have a fixed number of things in them. We call each thing
in a tuple an element. So in the tuple <c>{moscow,{c,-10}}</c>,
element 1 is <c>moscow</c> and element 2 is <c>{c,-10}</c>. I
have chosen <c>c</c> meaning Centigrade (or Celsius) and <c>f</c>
meaning Fahrenheit.</p>
</section>
<section>
<title>Lists</title>
<p>Whereas tuples group things together, we also want to be able to
represent lists of things. Lists in Erlang are surrounded by "["
and "]". For example a list of the temperatures of various cities
in the world could be:</p>
<code type="none">
[{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}},
{paris, {f, 28}}, {london, {f, 36}}]</code>
<p>Note that this list was so long that it didn't fit on one line.
This doesn't matter, Erlang allows line breaks at all "sensible
places" but not, for example, in the middle of atoms, integers
etc.</p>
<p>A very useful way of looking at parts of lists, is by using "|".
This is best explained by an example using the shell.</p>
<pre>
17> <input>[First |TheRest] = [1,2,3,4,5].</input>
[1,2,3,4,5]
18> <input>First.</input>
1
19> <input>TheRest.</input>
[2,3,4,5]</pre>
<p>We use | to separate the first elements of the list from
the rest of the list. (<c>First</c> has got value 1 and
<c>TheRest</c> value [2,3,4,5]).</p>
<p>Another example:</p>
<pre>
20> <input>[E1, E2 | R] = [1,2,3,4,5,6,7].</input>
[1,2,3,4,5,6,7]
21> <input>E1.</input>
1
22> <input>E2.</input>
2
23> <input>R.</input>
[3,4,5,6,7]</pre>
<p>Here we see the use of | to get the first two elements from
the list. Of course if we try to get more elements from the list
than there are elements in the list we will get an error. Note
also the special case of the list with no elements [].</p>
<pre>
24> <input>[A, B | C] = [1, 2].</input>
[1,2]
25> <input>A.</input>
1
26> <input>B.</input>
2
27> <input>C.</input>
[]</pre>
<p>In all the examples above, I have been using new variable names,
not reusing the old ones: <c>First</c>, <c>TheRest</c>, <c>E1</c>,
<c>E2</c>, <c>R</c>, <c>A</c>, <c>B</c>, <c>C</c>. The reason
for this is that a variable can only be given a value once in its
context (scope). I'll get back to this later, it isn't so
peculiar as it sounds!</p>
<p>The following example shows how we find the length of a list:</p>
<code type="none">
-module(tut4).
-export([list_length/1]).
list_length([]) ->
0;
list_length([First | Rest]) ->
1 + list_length(Rest).</code>
<p>Compile (file <c>tut4.erl</c>) and test:</p>
<pre>
28> <input>c(tut4).</input>
{ok,tut4}
29> <input>tut4:list_length([1,2,3,4,5,6,7]).</input>
7</pre>
<p>Explanation:</p>
<code type="none">
list_length([]) ->
0;</code>
<p>The length of an empty list is obviously 0.</p>
<code type="none">
list_length([First | Rest]) ->
1 + list_length(Rest).</code>
<p>The length of a list with the first element <c>First</c> and
the remaining elements <c>Rest</c> is 1 + the length of
<c>Rest</c>.</p>
<p>(Advanced readers only: This is not tail recursive, there is a
better way to write this function).</p>
<p>In general we can say we use tuples where we would use "records"
or "structs" in other languages and we use lists when we want to
represent things which have varying sizes, (i.e. where we would
use linked lists in other languages).</p>
<p>Erlang does not have a string date type, instead strings can be
represented by lists of ASCII characters. So the list
<c>[97,98,99]</c> is equivalent to "abc". The Erlang shell is
"clever" and guesses the what sort of list we mean and outputs it
in what it thinks is the most appropriate form, for example:</p>
<pre>
30> <input>[97,98,99].</input>
"abc"</pre>
</section>
<section>
<title>Standard Modules and Manual Pages</title>
<p>Erlang has a lot of standard modules to help you do things. For
example, the module <c>io</c> contains a lot of functions to help
you do formatted input/output. To look up information about
standard modules, the command <c>erl -man</c> can be used at
the operating shell or command prompt (i.e. at the same place as
that where you started <c>erl</c>). Try the operating system
shell command:</p>
<pre>
% <input>erl -man io</input>
ERLANG MODULE DEFINITION io(3)
MODULE
io - Standard I/O Server Interface Functions
DESCRIPTION
This module provides an interface to standard Erlang IO
servers. The output functions all return ok if they are suc-
...</pre>
<p>If this doesn't work on your system, the documentation is
included as HTML in the Erlang/OTP release, or you can read
the documentation as HTML or download it as PDF from either of
the sites www.erlang.se (commercial Erlang) or www.erlang.org
(open source), for example for release R9B:</p>
<code type="none">
http://www.erlang.org/doc/r9b/doc/index.html</code>
</section>
<section>
<title>Writing Output to a Terminal</title>
<p>It's nice to be able to do formatted output in these example, so
the next example shows a simple way to use to use
the <c>io:format</c> function. Of course, just like all other
exported functions, you can test the <c>io:format</c> function in
the shell:</p>
<pre>
31> <input>io:format("hello world~n", []).</input>
hello world
ok
32> <input>io:format("this outputs one Erlang term: ~w~n", [hello]).</input>
this outputs one Erlang term: hello
ok
33> <input>io:format("this outputs two Erlang terms: ~w~w~n", [hello, world]).</input>
this outputs two Erlang terms: helloworld
ok
34> <input>io:format("this outputs two Erlang terms: ~w ~w~n", [hello, world]).</input>
this outputs two Erlang terms: hello world
ok</pre>
<p>The function <c>format/2</c> (i.e. <c>format</c> with two
arguments) takes two lists. The first one is nearly always a list
written between " ". This list is printed out as it stands,
except that each ~w is replaced by a term taken in order from
the second list. Each ~n is replaced by a new line.
The <c>io:format/2</c> function itself returns the atom <c>ok</c>
if everything goes as planned. Like other functions in Erlang, it
crashes if an error occurs. This is not a fault in Erlang, it is
a deliberate policy. Erlang has sophisticated mechanisms to
handle errors which we will show later. As an exercise, try to
make <c>io:format</c> crash, it shouldn't be difficult. But
notice that although <c>io:format</c> crashes, the Erlang shell
itself does not crash.</p>
</section>
<section>
<title>A Larger Example</title>
<p>Now for a larger example to consolidate what we have learnt so
far. Assume we have a list of temperature readings from a number
of cities in the world. Some of them are in Celsius (Centigrade)
and some in Fahrenheit (as in the previous list). First let's
convert them all to Celsius, then let's print out the data neatly.</p>
<code type="none">
%% This module is in file tut5.erl
-module(tut5).
-export([format_temps/1]).
%% Only this function is exported
format_temps([])-> % No output for an empty list
ok;
format_temps([City | Rest]) ->
print_temp(convert_to_celsius(City)),
format_temps(Rest).
convert_to_celsius({Name, {c, Temp}}) -> % No conversion needed
{Name, {c, Temp}};
convert_to_celsius({Name, {f, Temp}}) -> % Do the conversion
{Name, {c, (Temp - 32) * 5 / 9}}.
print_temp({Name, {c, Temp}}) ->
io:format("~-15w ~w c~n", [Name, Temp]).</code>
<pre>
35> <input>c(tut5).</input>
{ok,tut5}
36> <input>tut5:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},</input>
<input>{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).</input>
moscow -10 c
cape_town 21.11111111111111 c
stockholm -4 c
paris -2.2222222222222223 c
london 2.2222222222222223 c
ok</pre>
<p>Before we look at how this program works, notice that we have
added a few comments to the code. A comment starts with a %
character and goes on to the end of the line. Note as well that
the <c>-export([format_temps/1]).</c> line only includes
the function <c>format_temps/1</c>, the other functions are
<em>local</em> functions, i.e. they are not visible from outside
the module <c>tut5</c>.</p>
<p>Note as well that when testing the program from the shell, I had
to spread the input over two lines as the line was too long.</p>
<p>When we call <c>format_temps</c> the first time, <c>City</c>
gets the value <c>{moscow,{c,-10}}</c> and <c>Rest</c> is
the rest of the list. So we call the function
<c>print_temp(convert_to_celsius({moscow,{c,-10}}))</c>.</p>
<p>Here we see a function call as
<c>convert_to_celsius({moscow,{c,-10}})</c> as the argument to
the function <c>print_temp</c>. When we <em>nest</em> function
calls like this we execute (evaluate) them from the inside out.
I.e. we first evaluate <c>convert_to_celsius({moscow,{c,-10}})</c>
which gives the value <c>{moscow,{c,-10}}</c> as the temperature
is already in Celsius and then we evaluate
<c>print_temp({moscow,{c,-10}})</c>. The function
<c>convert_to_celsius</c> works in a similar way to
the <c>convert_length</c> function in the previous example.</p>
<p><c>print_temp</c> simply calls <c>io:format</c> in a similar way
to what has been described above. Note that ~-15w says to print
the "term" with a field length (width) of 15 and left justify it.
(<seealso marker="stdlib:io#fwrite/1">io(3)</seealso>).</p>
<p>Now we call <c>format_temps(Rest)</c> with the rest of the list
as an argument. This way of doing things is similar to the loop
constructs in other languages. (Yes, this is recursion, but don't
let that worry you). So the same <c>format_temps</c> function is
called again, this time <c>City</c> gets the value
<c>{cape_town,{f,70}}</c> and we repeat the same procedure as
before. We go on doing this until the list becomes empty, i.e. [],
which causes the first clause <c>format_temps([])</c> to match.
This simply returns (results in) the atom <c>ok</c>, so
the program ends.</p>
</section>
<section>
<title>Matching, Guards and Scope of Variables</title>
<p>It could be useful to find the maximum and minimum temperature
in lists like this. Before extending the program to do this,
let's look at functions for finding the maximum value of
the elements in a list:</p>
<code type="none">
-module(tut6).
-export([list_max/1]).
list_max([Head|Rest]) ->
list_max(Rest, Head).
list_max([], Res) ->
Res;
list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
list_max(Rest, Head);
list_max([Head|Rest], Result_so_far) ->
list_max(Rest, Result_so_far).</code>
<pre>
37> <input>c(tut6).</input>
{ok,tut6}
38> <input>tut6:list_max([1,2,3,4,5,7,4,3,2,1]).</input>
7</pre>
<p>First note that we have two functions here with the same name
<c>list_max</c>. However each of these takes a different number
of arguments (parameters). In Erlang these are regarded as
completely different functions. Where we need to distinguish
between these functions we write <c>name/arity</c>, where
<c>name</c> is the name of the function and <c>arity</c> is
the number of arguments, in this case <c>list_max/1</c> and
<c>list_max/2</c>.</p>
<p>This is an example where we walk through a list "carrying" a
value with us, in this case <c>Result_so_far</c>.
<c>list_max/1</c> simply assumes that the max value of the list
is the head of the list and calls <c>list_max/2</c> with the rest
of the list and the value of the head of the list, in the above
this would be <c>list_max([2,3,4,5,7,4,3,2,1],1)</c>. If we tried
to use <c>list_max/1</c> with an empty list or tried to use it
with something which isn't a list at all, we would cause an error.
Note that the Erlang philosophy is not to handle errors of this
type in the function they occur, but to do so elsewhere. More
about this later.</p>
<p>In <c>list_max/2</c> we walk down the list and use <c>Head</c>
instead of <c>Result_so_far</c> when <c>Head</c> >
<c>Result_so_far</c>. <c>when</c> is a special word we use before
the -> in the function to say that we should only use this part
of the function if the test which follows is true. We call tests
of this type a <em>guard</em>. If the guard isn't true (we say
the guard fails), we try the next part of the function. In this
case if <c>Head</c> isn't greater than <c>Result_so_far</c> then
it must be smaller or equal to is, so we don't need a guard on
the next part of the function.</p>
<p>Some useful operators in guards are, < less than, >
greater than, == equal, >= greater or equal, =< less or
equal, /= not equal. (see the chapter
<seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual).</p>
<p>To change the above program to one which works out the minimum
value of the element in a list, all we would need to do is to
write < instead of >. (But it would be wise to change
the name of the function to <c>list_min</c> :-).</p>
<p>Remember that I mentioned earlier that a variable could only be
given a value once in its scope? In the above we see, for example,
that <c>Result_so_far</c> has been given several values. This is
OK since every time we call <c>list_max/2</c> we create a new
scope and one can regard the <c>Result_so_far</c> as a completely
different variable in each scope.</p>
<p>Another way of creating and giving a variable a value is by using
the match operator = . So if I write <c>M = 5</c>, a variable
called <c>M</c> will be created and given the value 5. If, in
the same scope I then write <c>M = 6</c>, I'll get an error. Try
this out in the shell:</p>
<pre>
39> <input>M = 5.</input>
5
40> <input>M = 6.</input>
** exception error: no match of right hand side value 6
41> <input>M = M + 1.</input>
** exception error: no match of right hand side value 6
42> <input>N = M + 1.</input>
6</pre>
<p>The use of the match operator is particularly useful for pulling
apart Erlang terms and creating new ones.</p>
<pre>
43> <input>{X, Y} = {paris, {f, 28}}.</input>
{paris,{f,28}}
44> <input>X.</input>
paris
45> <input>Y.</input>
{f,28}</pre>
<p>Here we see that <c>X</c> gets the value <c>paris</c> and
<c>Y</c><c>{f,28}</c>.</p>
<p>Of course if we try to do the same again with another city, we
get an error:</p>
<pre>
46> <input>{X, Y} = {london, {f, 36}}.</input>
** exception error: no match of right hand side value {london,{f,36}}</pre>
<p>Variables can also be used to improve the readability of
programs, for example, in the <c>list_max/2</c> function above,
we could write:</p>
<code type="none">
list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
New_result_far = Head,
list_max(Rest, New_result_far);</code>
<p>which is possibly a little clearer.</p>
</section>
<section>
<title>More About Lists</title>
<p>Remember that the | operator can be used to get the head of a
list:</p>
<pre>
47> <input>[M1|T1] = [paris, london, rome].</input>
[paris,london,rome]
48> <input>M1.</input>
paris
49> <input>T1.</input>
[london,rome]</pre>
<p>The | operator can also be used to add a head to a list:</p>
<pre>
50> <input>L1 = [madrid | T1].</input>
[madrid,london,rome]
51> <input>L1.</input>
[madrid,london,rome]</pre>
<p>Now an example of this when working with lists - reversing
the order of a list:</p>
<code type="none">
-module(tut8).
-export([reverse/1]).
reverse(List) ->
reverse(List, []).
reverse([Head | Rest], Reversed_List) ->
reverse(Rest, [Head | Reversed_List]);
reverse([], Reversed_List) ->
Reversed_List.</code>
<pre>
52> <input>c(tut8).</input>
{ok,tut8}
53> <input>tut8:reverse([1,2,3]).</input>
[3,2,1]</pre>
<p>Consider how <c>Reversed_List</c> is built. It starts as [], we
then successively take off the heads of the list to be reversed
and add them to the the <c>Reversed_List</c>, as shown in
the following:</p>
<code type="none">
reverse([1|2,3], []) =>
reverse([2,3], [1|[]])
reverse([2|3], [1]) =>
reverse([3], [2|[1])
reverse([3|[]], [2,1]) =>
reverse([], [3|[2,1]])
reverse([], [3,2,1]) =>
[3,2,1]</code>
<p>The module <c>lists</c> contains a lot of functions for
manipulating lists, for example for reversing them, so before you
write a list manipulating function it is a good idea to check
that one isn't already written for you. (see
<seealso marker="stdlib:lists">lists(3)</seealso>).</p>
<p>Now lets get back to the cities and temperatures, but take a more
structured approach this time. First let's convert the whole list
to Celsius as follows and test the function:</p>
<code type="none">
-module(tut7).
-export([format_temps/1]).
format_temps(List_of_cities) ->
convert_list_to_c(List_of_cities).
convert_list_to_c([{Name, {f, F}} | Rest]) ->
Converted_City = {Name, {c, (F -32)* 5 / 9}},
[Converted_City | convert_list_to_c(Rest)];
convert_list_to_c([City | Rest]) ->
[City | convert_list_to_c(Rest)];
convert_list_to_c([]) ->
[].</code>
<pre>
54> <input>c(tut7).</input>
{ok, tut7}.
55> <input>tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},</input>
<input>{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).</input>
[{moscow,{c,-10}},
{cape_town,{c,21.11111111111111}},
{stockholm,{c,-4}},
{paris,{c,-2.2222222222222223}},
{london,{c,2.2222222222222223}}]</pre>
<p>Looking at this bit by bit:</p>
<code type="none">
format_temps(List_of_cities) ->
convert_list_to_c(List_of_cities).</code>
<p>Here we see that <c>format_temps/1</c> calls
<c>convert_list_to_c/1</c>. <c>convert_list_to_c/1</c> takes off
the head of the <c>List_of_cities</c>, converts it to Celsius if
needed. The | operator is used to add the (maybe) converted
to the converted rest of the list:</p>
<code type="none">
[Converted_City | convert_list_to_c(Rest)];</code>
<p>or</p>
<code type="none">
[City | convert_list_to_c(Rest)];</code>
<p>We go on doing this until we get to the end of the list (i.e.
the list is empty:</p>
<code type="none">
convert_list_to_c([]) ->
[].</code>
<p>Now we have converted the list, we add a function to print it:</p>
<code type="none">
-module(tut7).
-export([format_temps/1]).
format_temps(List_of_cities) ->
Converted_List = convert_list_to_c(List_of_cities),
print_temp(Converted_List).
convert_list_to_c([{Name, {f, F}} | Rest]) ->
Converted_City = {Name, {c, (F -32)* 5 / 9}},
[Converted_City | convert_list_to_c(Rest)];
convert_list_to_c([City | Rest]) ->
[City | convert_list_to_c(Rest)];
convert_list_to_c([]) ->
[].
print_temp([{Name, {c, Temp}} | Rest]) ->
io:format("~-15w ~w c~n", [Name, Temp]),
print_temp(Rest);
print_temp([]) ->
ok.</code>
<pre>
56> <input>c(tut7).</input>
{ok,tut7}
57> <input>tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},</input>
<input>{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).</input>
moscow -10 c
cape_town 21.11111111111111 c
stockholm -4 c
paris -2.2222222222222223 c
london 2.2222222222222223 c
ok</pre>
<p>We now have to add a function to find the cities with
the maximum and minimum temperatures. The program below isn't
the most efficient way of doing this as we walk through the list
of cities four times. But it is better to first strive for
clarity and correctness and to make programs efficient only if
really needed.</p>
<code type="none"><![CDATA[
-module(tut7).
-export([format_temps/1]).
format_temps(List_of_cities) ->
Converted_List = convert_list_to_c(List_of_cities),
print_temp(Converted_List),
{Max_city, Min_city} = find_max_and_min(Converted_List),
print_max_and_min(Max_city, Min_city).
convert_list_to_c([{Name, {f, Temp}} | Rest]) ->
Converted_City = {Name, {c, (Temp -32)* 5 / 9}},
[Converted_City | convert_list_to_c(Rest)];
convert_list_to_c([City | Rest]) ->
[City | convert_list_to_c(Rest)];
convert_list_to_c([]) ->
[].
print_temp([{Name, {c, Temp}} | Rest]) ->
io:format("~-15w ~w c~n", [Name, Temp]),
print_temp(Rest);
print_temp([]) ->
ok.
find_max_and_min([City | Rest]) ->
find_max_and_min(Rest, City, City).
find_max_and_min([{Name, {c, Temp}} | Rest],
{Max_Name, {c, Max_Temp}},
{Min_Name, {c, Min_Temp}}) ->
if
Temp > Max_Temp ->
Max_City = {Name, {c, Temp}}; % Change
true ->
Max_City = {Max_Name, {c, Max_Temp}} % Unchanged
end,
if
Temp < Min_Temp ->
Min_City = {Name, {c, Temp}}; % Change
true ->
Min_City = {Min_Name, {c, Min_Temp}} % Unchanged
end,
find_max_and_min(Rest, Max_City, Min_City);
find_max_and_min([], Max_City, Min_City) ->
{Max_City, Min_City}.
print_max_and_min({Max_name, {c, Max_temp}}, {Min_name, {c, Min_temp}}) ->
io:format("Max temperature was ~w c in ~w~n", [Max_temp, Max_name]),
io:format("Min temperature was ~w c in ~w~n", [Min_temp, Min_name]).]]></code><pre>
58> <input>c(tut7).</input>
{ok, tut7}
59> <input>tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},</input>
<input>{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).</input>
moscow -10 c
cape_town 21.11111111111111 c
stockholm -4 c
paris -2.2222222222222223 c
london 2.2222222222222223 c
Max temperature was 21.11111111111111 c in cape_town
Min temperature was -10 c in moscow
ok</pre>
</section>
<section>
<title>If and Case</title>
<p>The function <c>find_max_and_min</c> works out the maximum and
minimum temperature. We have introduced a new construct here
<c>if</c>. If works as follows:</p>
<code type="none">
if
Condition 1 ->
Action 1;
Condition 2 ->
Action 2;
Condition 3 ->
Action 3;
Condition 4 ->
Action 4
end</code>
<p>Note there is no ";" before <c>end</c>! Conditions are the same
as guards, tests which succeed or fail. Erlang starts at the top
until it finds a condition which succeeds and then it evaluates
(performs) the action following the condition and ignores all
other conditions and action before the <c>end</c>. If no
condition matches, there will be a run-time failure. A condition
which always is succeeds is the atom, <c>true</c> and this is
often used last in an <c>if</c> meaning do the action following
the <c>true</c> if all other conditions have failed.</p>
<p>The following is a short program to show the workings of
<c>if</c>.</p>
<code type="none">
-module(tut9).
-export([test_if/2]).
test_if(A, B) ->
if
A == 5 ->
io:format("A == 5~n", []),
a_equals_5;
B == 6 ->
io:format("B == 6~n", []),
b_equals_6;
A == 2, B == 3 -> %i.e. A equals 2 and B equals 3
io:format("A == 2, B == 3~n", []),
a_equals_2_b_equals_3;
A == 1 ; B == 7 -> %i.e. A equals 1 or B equals 7
io:format("A == 1 ; B == 7~n", []),
a_equals_1_or_b_equals_7
end.</code>
<p>Testing this program gives:</p>
<pre>
60> <input>c(tut9).</input>
{ok,tut9}
61> <input>tut9:test_if(5,33).</input>
A == 5
a_equals_5
62> <input>tut9:test_if(33,6).</input>
B == 6
b_equals_6
63> <input>tut9:test_if(2, 3).</input>
A == 2, B == 3
a_equals_2_b_equals_3
64> <input>tut9:test_if(1, 33).</input>
A == 1 ; B == 7
a_equals_1_or_b_equals_7
65> <input>tut9:test_if(33, 7).</input>
A == 1 ; B == 7
a_equals_1_or_b_equals_7
66> <input>tut9:test_if(33, 33).</input>
** exception error: no true branch found when evaluating an if expression
in function tut9:test_if/2</pre>
<p>Notice that <c>tut9:test_if(33,33)</c> did not cause any
condition to succeed so we got the run time error
<c>if_clause</c>, here nicely formatted by the shell. See the chapter
<seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual for details
of the many guard tests available. <c>case</c> is another
construct in Erlang. Recall that we wrote the
<c>convert_length</c> function as:</p>
<code type="none">
convert_length({centimeter, X}) ->
{inch, X / 2.54};
convert_length({inch, Y}) ->
{centimeter, Y * 2.54}.</code>
<p>We could also write the same program as:</p>
<code type="none">
-module(tut10).
-export([convert_length/1]).
convert_length(Length) ->
case Length of
{centimeter, X} ->
{inch, X / 2.54};
{inch, Y} ->
{centimeter, Y * 2.54}
end.</code>
<pre>
67> <input>c(tut10).</input>
{ok,tut10}
68> <input>tut10:convert_length({inch, 6}).</input>
{centimeter,15.24}
69> <input>tut10:convert_length({centimeter, 2.5}).</input>
{inch,0.984251968503937}</pre>
<p>Notice that both <c>case</c> and <c>if</c> have <em>return values</em>, i.e. in the above example <c>case</c> returned
either <c>{inch,X/2.54}</c> or <c>{centimeter,Y*2.54}</c>.
The behaviour of <c>case</c> can also be modified by using guards.
An example should hopefully clarify this. The following example
tells us the length of a month, given the year. We need to know
the year of course, since February has 29 days in a leap year.</p>
<code type="none">
-module(tut11).
-export([month_length/2]).
month_length(Year, Month) ->
%% All years divisible by 400 are leap
%% Years divisible by 100 are not leap (except the 400 rule above)
%% Years divisible by 4 are leap (except the 100 rule above)
Leap = if
trunc(Year / 400) * 400 == Year ->
leap;
trunc(Year / 100) * 100 == Year ->
not_leap;
trunc(Year / 4) * 4 == Year ->
leap;
true ->
not_leap
end,
case Month of
sep -> 30;
apr -> 30;
jun -> 30;
nov -> 30;
feb when Leap == leap -> 29;
feb -> 28;
jan -> 31;
mar -> 31;
may -> 31;
jul -> 31;
aug -> 31;
oct -> 31;
dec -> 31
end.</code>
<pre>
70> <input>c(tut11).</input>
{ok,tut11}
71> <input>tut11:month_length(2004, feb).</input>
29
72> <input>tut11:month_length(2003, feb).</input>
28
73> <input>tut11:month_length(1947, aug).</input>
31</pre>
</section>
<section>
<title>Built In Functions (BIFs)</title>
<p>Built in functions BIFs are functions which for some reason is
built in to the Erlang virtual machine. BIFs often implement
functionality that is impossible to implement in Erlang or is to
inefficient to implement in Erlang. Some BIFs can be called
by use of the function name only but they are by default belonging
to the erlang module so for example the call to the BIF <c>trunc</c>
below is equivalent with a call to <c>erlang:trunc</c>.</p>
<p>As you can see, we first find out if a year is leap or not. If a
year is divisible by 400, it is a leap year. To find this out we
first divide the year by 400 and use the built in function
<c>trunc</c> (more later) to cut off any decimals. We then
multiply by 400 again and see if we get back the same value. For
example, year 2004:</p>
<code type="none">
2004 / 400 = 5.01
trunc(5.01) = 5
5 * 400 = 2000</code>
<p>and we can see that we got back 2000 which is not the same as
2004, so 2004 isn't divisible by 400. Year 2000:</p>
<code type="none">
2000 / 400 = 5.0
trunc(5.0) = 5
5 * 400 = 2000</code>
<p>so we have a leap year. The next two tests if the year is
divisible by 100 or 4 are done in the same way. The first
<c>if</c> returns <c>leap</c> or <c>not_leap</c> which lands up
in the variable <c>Leap</c>. We use this variable in the guard
for <c>feb</c> in the following <c>case</c> which tells us how
long the month is.</p>
<p>This example showed the use of <c>trunc</c>, an easier way would
be to use the Erlang operator <c>rem</c> which gives the remainder
after division. For example:</p>
<pre>
74> <input>2004 rem 400.</input>
4</pre>
<p>so instead of writing</p>
<code type="none">
trunc(Year / 400) * 400 == Year ->
leap;</code>
<p>we could write</p>
<code type="none">
Year rem 400 == 0 ->
leap;</code>
<p>There are many other built in functions (BIF) such as
<c>trunc</c>. Only a few built in functions can be used in guards,
and you cannot use functions you have defined yourself in guards.
(see the chapter
<seealso marker="doc/reference_manual:expressions">"Guard Sequences"</seealso> in the Erlang Reference Manual) (Aside for
advanced readers: This is to ensure that guards don't have side
effects). Let's play with a few of these functions in the shell:</p>
<pre>
75> <input>trunc(5.6).</input>
5
76> <input>round(5.6).</input>
6
77> <input>length([a,b,c,d]).</input>
4
78> <input>float(5).</input>
5.0
79> <input>is_atom(hello).</input>
true
80> <input>is_atom("hello").</input>
false
81> <input>is_tuple({paris, {c, 30}}).</input>
true
82> <input>is_tuple([paris, {c, 30}]).</input>
false</pre>
<p>All the above can be used in guards. Now for some which can't be
used in guards:</p>
<pre>
83> <input>atom_to_list(hello).</input>
"hello"
84> <input>list_to_atom("goodbye").</input>
goodbye
85> <input>integer_to_list(22).</input>
"22"</pre>
<p>The 3 BIFs above do conversions which would be difficult (or
impossible) to do in Erlang.</p>
</section>
<section>
<title>Higher Order Functions (Funs)</title>
<p>Erlang, like most modern functional programming languages, has
higher order functions. We start with an example using the shell:</p>
<pre>
86> <input>Xf = fun(X) -> X * 2 end.</input>
#Fun<erl_eval.5.123085357>
87> <input>Xf(5).</input>
10</pre>
<p>What we have done here is to define a function which doubles
the value of number and assign this function to a variable. Thus
<c>Xf(5)</c> returned the value 10. Two useful functions when
working with lists are <c>foreach</c> and <c>map</c>, which are
defined as follows:</p>
<code type="none">
foreach(Fun, [First|Rest]) ->
Fun(First),
foreach(Fun, Rest);
foreach(Fun, []) ->
ok.
map(Fun, [First|Rest]) ->
[Fun(First)|map(Fun,Rest)];
map(Fun, []) ->
[].</code>
<p>These two functions are provided in the standard module
<c>lists</c>. <c>foreach</c> takes a list and applies a fun to
every element in the list, <c>map</c> creates a new list by
applying a fun to every element in a list. Going back to
the shell, we start by using <c>map</c> and a fun to add 3 to
every element of a list:</p>
<pre>
88> <input>Add_3 = fun(X) -> X + 3 end.</input>
#Fun<erl_eval.5.123085357>
89> <input>lists:map(Add_3, [1,2,3]).</input>
[4,5,6]</pre>
<p>Now lets print out the temperatures in a list of cities (yet
again):</p>
<pre>
90> <input>Print_City = fun({City, {X, Temp}}) -> io:format("~-15w ~w ~w~n",</input>
<input>[City, X, Temp]) end.</input>
#Fun<erl_eval.5.123085357>
91> <input>lists:foreach(Print_City, [{moscow, {c, -10}}, {cape_town, {f, 70}},</input>
<input>{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).</input>
moscow c -10
cape_town f 70
stockholm c -4
paris f 28
london f 36
ok</pre>
<p>We will now define a fun which can be used to go through a list
of cities and temperatures and transform them all to Celsius.</p>
<code type="none">
-module(tut13).
-export([convert_list_to_c/1]).
convert_to_c({Name, {f, Temp}}) ->
{Name, {c, trunc((Temp - 32) * 5 / 9)}};
convert_to_c({Name, {c, Temp}}) ->
{Name, {c, Temp}}.
convert_list_to_c(List) ->
lists:map(fun convert_to_c/1, List).</code>
<pre>
92> <input>tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},</input>
<input>{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).</input>
[{moscow,{c,-10}},
{cape_town,{c,21}},
{stockholm,{c,-4}},
{paris,{c,-2}},
{london,{c,2}}]</pre>
<p>The <c>convert_to_c</c> function is the same as before, but we
use it as a fun:</p>
<code type="none">
lists:map(fun convert_to_c/1, List)</code>
<p>When we use a function defined elsewhere as a fun we can refer
to it as <c>Function/Arity</c> (remember that <c>Arity</c> =
number of arguments). So in the <c>map</c> call we write
<c>lists:map(fun convert_to_c/1, List)</c>. As you can see
<c>convert_list_to_c</c> becomes much shorter and easier to
understand.</p>
<p>The standard module <c>lists</c> also contains a function
<c>sort(Fun, List)</c> where <c>Fun</c> is a fun with two
arguments. This fun should return <c>true</c> if the the first
argument is less than the second argument, or else <c>false</c>.
We add sorting to the <c>convert_list_to_c</c>:</p>
<code type="none"><![CDATA[
-module(tut13).
-export([convert_list_to_c/1]).
convert_to_c({Name, {f, Temp}}) ->
{Name, {c, trunc((Temp - 32) * 5 / 9)}};
convert_to_c({Name, {c, Temp}}) ->
{Name, {c, Temp}}.
convert_list_to_c(List) ->
New_list = lists:map(fun convert_to_c/1, List),
lists:sort(fun({_, {c, Temp1}}, {_, {c, Temp2}}) ->
Temp1 < Temp2 end, New_list).]]></code>
<pre>
93> <input>c(tut13).</input>
{ok,tut13}
94> <input>tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},</input>
<input>{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).</input>
[{moscow,{c,-10}},
{stockholm,{c,-4}},
{paris,{c,-2}},
{london,{c,2}},
{cape_town,{c,21}}]</pre>
<p>In <c>sort</c> we use the fun:</p>
<code type="none"><![CDATA[
fun({_, {c, Temp1}}, {_, {c, Temp2}}) -> Temp1 < Temp2 end,]]></code>
<p>Here we introduce the concept of an <em>anonymous variable</em>
"_". This is simply shorthand for a variable which is going to
get a value, but we will ignore the value. This can be used
anywhere suitable, not just in fun's. <c><![CDATA[Temp1 < Temp2]]></c>
returns <c>true</c> if <c>Temp1</c> is less than <c>Temp2</c>.</p>
</section>
</chapter>