Erlang Introduction
by "Blag" - Senior Developer Evangelist
What is Erlang?
Erlang is a general-purpose concurrent, garbage-collected programming language and runtime system.
It's also a functional language, with eager evaluation, single assignment and dynamic typing.
Designed by Ericsson - hence the name "Ericsson Language".
Now it's Open Source.
Makes you throw away all your previous programming dogmas.
How to install Erlang?
Erlang can be downloaded from here Erlang
Windows and Mac version comes as a Binary File. Windows comes with a really nice shell.
Linux version can be installed from source or using apt-get.
erlide is an Eclipse based IDE.
For Linux or Windows we can (and we're going to use) Geany.
If you're on Mac follow this Geany OSX.
Who uses Erlang?
- Amazon -> SimpleDB, providing database services as part or EC2
- Yahoo! -> Delicious, which has more than 5 million users and 150 million bookmarked URLs
- Facebook -> Backend of its chat service, with more than 100 million active users
- WhatsApp -> Messaging services, achieving 2 million connected users per server
- T-Mobile -> SMS and authentication systems
- Ericsson -> Support nodes, used in GPRS and 3G networks worldwide
- CouchDB -> "Schema-less" document oriented database
Starting out...
To begin with...we're going to call Erlang from the terminal.

Variables
Variables are not variable...
Once assigned...variables cannot change...they're immutable...
MyVariable = "This is my variable".
"This is my variable"
MyVariable = "This could be your variable".
** exception error: no match of right hand side
value "This could be your variable"
Every command must end with a period "."
Variables must start with an Uppercase letter.
Starting with a Lowercase letter creates an "atom".
Atoms are not variables, but string representations...like Constants.
Erlang has dynamic typing...what you assign to a value, it becomes its type...
thisisanatom.
thisisanatom
thisisanatom = "My Atom".
** exception error: no match of right hand side
value "My Atom"
IntegerValue = 1977.
1977
Variables can't change their values after assignment...
So how can we update their values?
We can't...we need to use a new variable...
X = 10.
10
X = 10 + 5.
** exception error: no match of right hand
side value 15
Y = X + 5.
15
Tuples
Sometimes, we need to group values together...
For that, we can use Tuples...
Person = {blag,37}.
{blag,37}
{Name,Age} = Person.
{blag,37}
Name.
blag
We can create nested tuples...
AnotherPerson = {wolverine,210}.
{wolverine,210}
People = {Person,AnotherPerson}.
{{blag,37},{wolverine,210}}
Lists
We can use Lists to handle Tuples in a better way...
People = [{blag,37},{wolverine,210},{bart,11}].
[{blag,37},{wolverine,210},{bart,11}]
[Head|Tail] = People.
[{blag,37},{wolverine,210},{bart,11}]
Head.
{blag,37}
Tail.
[{wolverine,210},{bart,11}]
Strings
Strings are not strings...They're a list of integers...
"Hello World".
"Hello World"
[72,101,108,108,111,32,87,111,114,108,100].
"Hello World"
$H.
72
[87].
"W"
Our first application
For this application we need to create a file called "greetings.erl" (with all lowercase)...
-module(greetings).
-export([greet/2]).
greet(male, Name) ->
io:format("Good morning Mr. ~s~n", [Name]);
greet(female, Name) ->
io:format("Good morning Mrs. ~s~n", [Name]);
greet(_, Name) ->
io:format("Good morning ???. ~s~n", [Name]).
Before we can call our App, we need to compile it...
On Geany, just click the "Compile the current file" button.
Then you will need to click the "Run or view the current file" button.
If you're not using Geany then from the command line call...
erlc "name_of_file" to compile
erl and the "filename:functionname(parameters) to run it...
When we run it we're going to see...

Functions
Function are very important...In Erlang everything is a function.
There's no such things as Classes or Objects.
We can define the same function name with different number of parameters.
They will be treated as completely different functions.
Recursion is very important...we'll see that later...
Our second application
This example will call the same function with different number of parameters...
You can call it "numbers.erl" (with all lowercase)
-module(numbers).
-export([num/1,num/2]).
num(Number) ->
io:format("This is your number ~p~n",[Number]).
num(Number1,Number2) ->
io:format("This is the sum of two numbers ~p~n",
[Number1 + Number2]).
When we run it we're going to see...

Recursion
Recursion is one of the key points in Erlang...you call a function that calls itself multiple times.
As we can't change the value of a variable, we can pass different values as parameters.
This way we can update the variable value without changing the variable value...
Also, we can use something called "Pattern Matching" which is used to determine which function to call...
Our third application
This example will create a Fibonacci Number Generator.
You can call it "fibonacci.erl" (with all lowercase)
-module(fibonacci).
-export([fib/1]).
fib(Number) ->
fib(Number,0,1,"").
fib(1,_,_,Acc) ->
io:format("~p~n",["0 1 " ++ Acc]);
fib(Number,A,B,Acc) when A > 0 ->
fib(Number - 1, A + B, A, Acc ++
integer_to_list(A + B) ++ " ");
fib(Number,A,B,Acc) ->
fib(Number - 1, A + B, B, Acc ++
integer_to_list(A + B) ++ " ").
When we run it we're going to see...

Making an LED Number App
Name your file "led_Numbers.erl"
-module(led_Numbers).
-export([showLED/1]).
showLED(Number) when is_integer(Number) ->
Digits = [ X - 48 ||
X <- integer_to_list(Number) ],
Leds = #{0 => {" _ ","| | ","|_| "},
1 => {" ","| ","| "},
2 => {" _ "," _| ","|_ "},
3 => {"_ ","_| ","_| "},
4 => {" ","|_| "," | "},
5 => {" _ ","|_ "," _| "},
6 => {" _ ","|_ ","|_| "},
7 => {"_ "," | "," | "},
8 => {" _ ","|_| ","|_| "},
9 => {" _ ","|_| "," _| "}},
build_output(Digits,Digits,Leds,1,"").
build_output([],_,_,3,Acc) ->
io:format("~s~n",[Acc]);
build_output([],Digits,Leds,LineNo,Acc) ->
build_output(Digits,Digits,Leds,
LineNo+1,Acc++"\n");
build_output([H|T],Digits,Leds,LineNo,Acc) ->
build_output(T, Digits,Leds,LineNo,
Acc++element(LineNo,
maps:get(H,Leds))).
When we run it we're going to see...

Random Names
This App will generate 100,000 random names using two 16 elements arrays
We will measure the runtime
Name your file "random_names.erl"
-module(random_names).
-export([show_names/0, run_names/0]).
show_names() ->
Names = ["Anne","Gigi","Blag","Juergen",
"Marek","Ingo","Lars","Julia",
"Danielle","Rocky","Julien",
"Uwe","Myles","Mike","Steven",
"Fanny"],
Last_Names = ["Hardy","Read","Tejada",
"Schmerder","Kowalkiewicz",
"Sauerzapf","Karg","Satsuta",
"Keene","Ongkowidjojo",
"Vayssiere","Kylau","Fenlon",
"Flynn","Taylor","Tan"],
generate_names(Names,Last_Names).
generate_names(Names,Last_Names) ->
_ = [ lists:nth(rand:uniform(16),Names)
++ " " ++
lists:nth(rand:uniform(16),Last_Names)
++ "\n" || _ <-lists:seq(1,100000) ],
io:format("Done").
run_names() ->
{Time, _} = timer:tc(random_names,show_names,[]),
RunTime = Time /1000000,
io:format("\n~p~n",[RunTime]).
When we run it we're going to see...

Less than a minute...that's impressive...
Decimal to Romans
This App will create a Roman Numeral based on a decimal number
This will include some nice commands...
Name your file "dectoroman.erl"
-module(dectoroman).
-export([showRomans/1]).
showRomans(Number) when is_integer(Number) ->
Roman_Nums = [{1000,"M"},{900,"CM"},{500,"D"},
{400,"CD"},{100,"C"},{90,"XC"},
{50,"L"},{40,"XL"},{10,"X"},
{9,"IX"},{5,"V"},{4,"IV"},
{1,"I"}],
showRomans(Number,Roman_Nums,1,"").
showRomans(0,_,_,Acc) ->
io:format("~s~n",[Acc]);
showRomans(Number,Roman_Nums,Counter,Acc) ->
case Number >=
element(1,lists:nth(Counter,Roman_Nums)) of
true -> showRomans(Number -
element(1,lists:nth(Counter,Roman_Nums)),
Roman_Nums,Counter,Acc ++
element(2,lists:nth(Counter,Roman_Nums)));
false -> showRomans(Number,Roman_Nums,
Counter + 1,Acc)
end.
When we run it we're going to see...

Concurrency
Create processes in Erlang is both easy and inexpensive.
We can create a dozen, hundrer or even thousand of processes...and they act independentely.
Name your file "concurrent.erl"
-module(concurrent).
-export([run/1]).
proc1(N) when N < 1000 ->
proc1(N+1);
proc1(N) ->
io:format("Process 1: ~p~n",[N]),
io:format("Sleeping~n"),
timer:sleep(3000).
proc2(N) when N < 1000 ->
proc2(N+1);
proc2(N) ->
io:format("Process 2: ~p~n",[N]).
run(N) ->
proc1(N),
proc2(N),
proc1(N),
proc2(N),
spawn(fun() -> proc1(N) end),
spawn(fun() -> proc2(N) end).
When we run it we're going to see...

Mnesia
Mnesia is Erlang's own DBMS...
It's bundled inside Erlang, so there's no need for third party components.
Also it's distributable over nodes.
It uses transactions making rollbacks, backups and restores a pretty easy task.
We're going to build an app to store Music Albums...
You can call it "mnesiadex.erl" (with all lowercase)
-module(mnesiadex).
-include_lib("stdlib/include/qlc.hrl").
-export([initialize/0,start/0,stop/0,add_album/3,
remove_album/1,show_albums/0,show_artist/1]).
-record(music, {id, artist, album}).
initialize() ->
mnesia:create_schema([node()]),
mnesia:start(),
mnesia:create_table(music,
[{attributes,record_info(fields, music)},
{disc_only_copies,[node()]}]),mnesia:stop().
start() ->
mnesia:start(),
mnesia:wait_for_tables([music], 20000).
stop() ->
mnesia:stop().
do(Q) ->
F = fun() -> qlc:e(Q) end,
{atomic, Val} = mnesia:transaction(F), Val.
add_album(Id, Artist, Album) ->
Row = #music{id=Id, artist=Artist, album=Album},
F = fun() ->
mnesia:write(Row)
end,
mnesia:transaction(F).
remove_album(Id) ->
Oid = {music, Id},
F = fun() ->
mnesia:delete(Oid)
end,
mnesia:transaction(F).
show_albums() ->
do(qlc:q([{X#music.album,X#music.artist} ||
X <- mnesia:table(music)])).
show_artist(Artist) ->
do(qlc:q([X#music.album ||
X <- mnesia:table(music),
X#music.artist =:= Artist])).
When we run it we're going to see...

That's all for now...
I hope you had some fun...
I hope you liked Erlang
I hope you will give Functional Programming a second look -;)
Contact Information
Blag --> blag@blagarts.com
@Blag on Twitter