ONLamp.com
oreilly.comSafari Books Online.Conferences.

advertisement


An Introduction to Erlang

by Gregory Brown
09/13/2007

These days, the functional languages are all the rage. You see more and more hackers from the traditionally vanilla languages trying out things like Haskell or Scheme or OCaml. Breaking away from an imperative tradition forces us to think in a different way, which is always a good thing.

Recently, I've heard a lot about Erlang, especially from curious members of the Ruby community. This article is the result of my quick dive into the language, and will hopefully serve as a starting point for anyone else who's been hearing the buzz, but hasn't taken the plunge yet.

For this article, I'm assuming you're familiar with the general ideas behind functional programming, and that you have at least a conceptual grasp of concurrency. I'm also counting on you having at least an intermediate level of experience programming in any language. However, I'm not assuming you know any Erlang, so don't worry if this is the first time you've ever heard of the language.

Why Learn Erlang?

There are a lot of functional languages out there. All of them have their strong points and their foibles. Some seem wholly academic, while others are as pragmatic as the best object oriented languages out there. Choosing which languages to study is really a matter of figuring out what concepts you want to learn.

Erlang is known for an extremely elegant concurrency model. I've always been one to cringe at the mention of things like mutex locks, race conditions, and the entire motley crew of conceptual baggage that typically come along with any sort of parallel programming.

Joe Armstrong claims in "Programming Erlang" that because Erlang is designed from the ground up for concurrency, it makes life a lot easier. This, along with the promise of a small, efficient, and well thought out language implementation was enough to get me interested.

We'll start by going through the nuts and bolts of the language, and eventually ramp up to a simple concurrent program in Erlang that implements a basic chat system. Though it's far from fancy, it will show you how spinning off a few processes and getting them to communicate is almost trivial in Erlang.

Hello Erlang

It seems like screen I/O is something that often comes in the middle of functional programming texts, and though that's not necessarily a bad thing, a lot of us are used to the instant gratification of a "Hello World" program.

It's really nothing fancy, and if you run it as an Escript, it's quite simple:

#!/usr/bin/env escript

main(_) ->
  io:format("Hello World\n").

From the *nix shell:

$ chmod +x hello 
$ ./hello 
Hello World 
$

What you're seeing there is a function definition for main(), which gets executed by our script. The io:format() is what does our screen output.

Of course, none of this is exciting. Let's take a look at a more functional friendly primer, which is defining factorial:

example.erl
-module(example).
-export([fact/1]).

fact(0) -> 1;
fact(N) -> N * fact(N-1).

This code represents a trivial Erlang module, which gives functions a namespace to live in. From this example, you can see that Erlang allows for piece-wise function definition, which makes the syntax quite pleasing to the eye for most folks who have an interest in mathematics.

To run this code, we'll make use of the Erlang shell, compiling the module and then running some basic tests:

$ erl
Erlang (BEAM) emulator version 5.5.5 [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.5.5  (abort with ^G)
1> c(example).
{ok,example}
2> example:fact(0).
1
3> example:fact(5).
120
4> example:fact(10).
3628800
5> example:fact(25).
15511210043330985984000000

What we've done here is actually compile our module and then run some examples, live in the shell, against the compiled code. Being able to easily build your modules from within the Erlang shell is very nice, it makes you almost forget that you're working with a compiled language.

When we call c(example), Erlang looks for a file called example.erl in the load path, which includes the current directory. When it finds it, it populates the object code in a file called example.beam. You can then use the code freely from the shell, and even can recompile when you make changes.

In this example you can see we call example:fact(n) and get the proper results back. Seeing how the function is invoked, it's easier to explain what the export() line in our file means:

-export([fact/1])

Here we are telling the compiler that we want the function fact() with one argument to be callable from outside the module definition. Without this line, we would not be able to call the function from the shell, because it would be private to the module.

In Erlang, a function definition with a different number of arguments is actually an entirely separate function, which is why we need to specify the number of arguments when exporting.

For example, this function shares nothing in common but the same name as our original fact definition:

fact(A,B) -> io:format("Chuck Norris kicks ~p people in ~p places ~n",[A,B]).

If we wanted to export this and use it in the shell, we can change our export code to look like this:

-export([fact/1,fact/2]).

You can see that both function definitions are now accessible:

1> c(example).
{ok,example}
2> example:fact(4,5).
Chuck Norris kicks 4 people in 5 places 
ok
3> example:fact(4).  
24

Of course, we're starting to get ahead of ourselves. Let's now take a look at some of the common language elements and control structures in Erlang, so that we can begin to do something useful with them.

Pages: 1, 2, 3, 4

Next Pagearrow





Sponsored by: