Erlang was the first functional programming language I took a shot at learning. I started with the Manning book Erlang in Action which also explained the OTP. The problem was that I was combining learning functional programming with the pretty fringe environment that is Erlang. So instead I took a break from that and decided to learn Haskell, and loved it.
Now I'm back and would like to pick up Erlang and its OTP library. Even if I don't end up using it, I think it'll teach me many interesting concepts that lend themselves to this new age of massively concurrent programs. Scala, for example, uses actor-based concurrency much like Erlang's, as well as supervision trees.
Modules generally take the following form. The first line contains the module directive, known as the export declaration, as in Haskell. This lists the functions and their arity.
This can be compiled from the shell with the
c(modulename) command. However, it's more likely to be compiled with the Erlang compiler
erlc, which produces a
beam file. It's possible to then run the program can then be run on the Erlang virtual machine with the
erl command, which uses
-s to specify the functions to evaluate, in order.
The following describes a file server. It defines a convenience function
start which spawns a process that forever performs the
loop function inside a particular directory, which simply waits for a message to be received and processes it. Notice that
loop performs a tail-recursive call; Erlang has tail-call optimization, so there's no need to worry about overflowing the stack.
This server simply responds to two simple messages: one which requests a file listing and another which request file contents. Notice that the messages are distinguished by pattern matching, which works on atoms as well, such as
The client simply serves to provide client-facing functions that abstract away the server protocol, i.e. the exact messages sent. These simply send the appropriate message and wait for the response.
spawn is an Erlang primitive that initiates a concurrent process and returns its identifier.
The way in which processes can interact is through sending messages, which is done using the
Processes are received in a
receive block by pattern matching on the messages.
Values are bound with the
= operator, like
let in Haskell. It's also possible to pattern match on the value. Value names start with capital letters. Names beginning with lowercase letters are symbolic constants called atoms 1.
Lists can be heterogeneous in Erlang.