2  Sequential Programming

2 Sequential Programming

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 bits of Erlang code can be written directly, and be evaluated to see what happens (see the shell(3) manual page in STDLIB).

Start the Erlang shell (in Linux or UNIX) by starting a shell or command interpreter in your operating system and typing erl. You will see something like this.

% erl
Erlang R15B (erts-5.9.1) [source] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.1  (abort with ^G)
1>

Type "2 + 5." in the shell and then press Enter (carriage return). Notice that you tell the shell you are done entering code by finishing with a full stop "." and a carriage return.

1> 2 + 5.
7
2>

As shown, the Erlang shell numbers the lines that can be entered, (as 1> 2>) and that it correctly says that 2 + 5 is 7. If you make writing mistakes in the shell, you can delete with the backspace key, as in most shells. There are many more editing commands in the shell (see tty - A command line interface in ERTS User's Guide).

(Notice that many line numbers given by the shell in the following examples are out of sequence. This is because this tutorial was written and code-tested in separate sessions).

Here is a bit more complex calculation:

2> (42 + 77) * 66 / 3.
2618.0

Notice the use of brackets, the multiplication operator "*", and the division operator "/", as in normal arithmetic (see Expressions).

Press Control-C to shut down the Erlang system and the Erlang shell.

The following output is shown:

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

Type "a" to leave the Erlang system.

Another way to shut down the Erlang system is by entering halt():

3> halt().
% 

A programming language is not much use if you only can run code from the shell. So here is a small Erlang program. Enter it into a file named tut.erl using a suitable text editor. The file name tut.erl is important, and also that it is in the same directory as the one where you started erl). If you are lucky your editor has an Erlang mode that makes it easier for you to enter and format your code nicely (see The Erlang mode for Emacs in Tools User's Guide), but you can manage perfectly well without. Here is the code to enter:

-module(tut).
-export([double/1]).

double(X) ->
    2 * X.

It is not hard to guess that this program doubles the value of numbers. The first two lines of the code are described later. Let us compile the program. This can be done in an Erlang shell as follows, where c means compile:

3> c(tut).
{ok,tut}

The {ok,tut} means that the compilation is OK. If it says "error" it means that there is some mistake in the text that you entered. Additional error messages gives an idea to what is wrong so you can modify the text and then try to compile the program again.

Now run the program:

4> tut:double(10).
20

As expected, double of 10 is 20.

Now let us get back to the first two lines of the code. Erlang programs are written in files. Each file contains an Erlang module. The first line of code in the module is the module name (see Modules):

-module(tut).

Thus, the module is called tut. Notice the full stop "." 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 this case the file name is tut.erl. When using a function in another module, the syntax module_name:function_name(arguments) is used. So the following means call function double in module tut with argument "10".

4> tut:double(10).

The second line says that the module tut contains a function called double, which takes one argument (X in our example):

-export([double/1]).

The second line also says that this function can be called from outside the module tut. More about this later. Again, notice the "." at the end of the line.

Now for a more complicated example, the factorial of a number. For example, the factorial of 4 is 4 * 3 * 2 * 1, which equals 24.

Enter the following code in a file named tut1.erl:

-module(tut1).
-export([fac/1]).

fac(1) ->
    1;
fac(N) ->
    N * fac(N - 1).

So this is a module, called tut1 that contains a function called fac>, which takes one argument, N.

The first part says that the factorial of 1 is 1.:

fac(1) ->
    1;

Notice that this part ends with a semicolon ";" that indicates that there is more of the function fac> to come.

The second part says that the factorial of N is N multiplied by the factorial of N - 1:

fac(N) ->
    N * fac(N - 1).

Notice that this part ends with a "." saying that there are no more parts of this function.

Compile the file:

5> c(tut1).
{ok,tut1}

And now calculate the factorial of 4.

6> tut1:fac(4).
24

Here the function fac> in module tut1 is called with argument 4.

A function can have many arguments. Let us expand the module tut1 with the function to multiply two numbers:

-module(tut1).
-export([fac/1, mult/2]).

fac(1) ->
    1;
fac(N) ->
    N * fac(N - 1).

mult(X, Y) ->
    X * Y.

Notice that it is also required to expand the -export line with the information that there is another function mult with two arguments.

Compile:

7> c(tut1).
{ok,tut1}

Try out the new function mult:

8> tut1:mult(3,4).
12

In this example the numbers are integers and the arguments in the functions in the code N, X, and Y are called variables. Variables must start with a capital letter (see Variables). Examples of variables are Number, ShoeSize, and Age.

Atom is another data type in Erlang. Atoms start with a small letter (see Atom), for example, charles, centimeter, and inch. Atoms are simply names, nothing else. They are not like variables, which can have a value.

Enter the next program in a file named tut2.erl). It can be useful for converting from inches to centimeters and conversely:

-module(tut2).
-export([convert/2]).

convert(M, inch) ->
    M / 2.54;

convert(N, centimeter) ->
    N * 2.54.

Compile:

9> c(tut2).
{ok,tut2}

Test:

10> tut2:convert(3, inch).
1.1811023622047243
11> tut2:convert(7, centimeter).
17.78

Notice the introduction of decimals (floating point numbers) without any explanation. Hopefully you can cope with that.

Let us see what happens if something other than centimeter or inch is entered in the convert function:

12> tut2:convert(3, miles).
** exception error: no function clause matching tut2:convert(3,miles) (tut2.erl, line 4)

The two parts of the convert function are called its clauses. As shown, miles is not part of either of the clauses. The Erlang system cannot match either of the clauses so an error message function_clause is returned. 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 v/1:

13> v(12).
{'EXIT',{function_clause,[{tut2,convert,
                                [3,miles],
                                [{file,"tut2.erl"},{line,4}]},
                          {erl_eval,do_apply,6,
                                    [{file,"erl_eval.erl"},{line,677}]},
                          {shell,exprs,7,[{file,"shell.erl"},{line,687}]},
                          {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]},
                          {shell,eval_loop,3,
                                 [{file,"shell.erl"},{line,627}]}]}}