Learning Erlang - Erlang Gaining Momentum

You may have noticed that I've been talking a bit about concurrency and Erlang recently.  I've started to notice that others are taking notice and giving Erlang another look.  I've been a fan of the language for a while, although it is a functional language ala a Haskell, OCaml, F# and so on, it's key strengths doesn't come necessarily from that, but from how it handles concurrency.  I'm really fond of the language succinctness and beauty using pattern matching, higher order functions and so on much as I have with F#.

Gaining Momentum

As I stated before, many people are starting to give Erlang another look.  For more than 20 years since its inception around 1987, Erlang has received little notice outside of the telecomm industry from whence it came.  Then in 1998, it was released as open source, but still not much momentum gathered around the language.  But, then things started to change recently.  Moore's law started to change, not from faster CPUs, but more cores to the CPUs.  Our traditional methods of sequential imperative programming couldn't scale and utilize a lot of the machine this way. 

Then we started thinking about locks, monitors, mutexes, but the programming model isn't exactly easy.  And to boot, they tend to be a bit low-level for most pieces that we need.  Instead, we need more constructs such as guaranteeing pure functions and this function is ok for concurrency at either a language level or at least a library level.  Erlang is designed with this in mind, as it is a functional language, so functions are values, and values are immutable.  But not only that, the isolation of the processes allows for lightweight processes with no shared state between them.  This allows for a given process to fail without taking down the whole system, another important concurrency item that is important.

With this, companies started to take notice.  As noted by a post by Chris Vertonghen in his post "Erlang, or Utility-computing vs. Appliance-computing", he notes a few items of interest such as:

Other places are also looking at Erlang.  According to the GitHub blog, there is a  project called egitd and is a replacement for the stock git-daemon that ships with git.  Erlang is perfect for these massively concurrent systems with good failover capabilities. 


Getting Started

Getting started in Erlang is pretty easy.  Joe Armstrong's Programming in Erlang book tells you all you need to know on how to set it up.  I downloaded the distribution from the Erlang site for the runtime and I used Eclipse with Erlide to run through the samples in the book.  I had no issues setting it up and it's quite easy to use. 

I highly recommend that you get Joe Armstrong's Programming Erlang book as well as check out the Pragmatic Programmer screencasts on Erlang which you can find here.

From the F# Perspective

I've stated before that Erlang-style messaging through mailboxes is already supported in F#.  But, it's nowhere near as capable as Erlang.  Let's hope these kinds of issues can be raised and added to the libraries.  But, let's look at it from another perspective.  If you know functional programming and F#, you shouldn't have trouble in Erlang whatsoever.  In fact, I have a few examples of functions written in both Erlang and F# that do the same thing. 

Pattern Matching

Pattern matching is pretty important in Erlang.  Such constructs as for loops do not exist, instead relying on patterns instead to handle the basic control flow.  Let's look at a simple area calculator written in Erlang.

-module(geometry)
-export(area/1)
area({rectangle, Width, Ht}) -> Width * Ht;
area({circle, R}) -> 3.14159 * R * R;
area({square, X}) -> X * X.

geometry:area({rectangle, 10, 5}).
geometry:area({circle, 1.4}).
geometry:area({square, 2.5}).

What this sample did was used a tuple to wrap up the type of rectangle, circle and square.  Then I create multiple area functions that are my pattern.  Then at the bottom, after compiling and exporting my functions through my module, I'm able to call the functions with the given values.  How about in F#?

module Geometry =
  type Shape = Circle of float | Rectangle of float * float | Square of float

  let area = function
    | Circle R -> 3.13159 * R * R
    | Rectangle (Width, Ht) -> Width * Ht
    | Square X -> X * X
 
Geometry.area (Geometry.Rectangle(10.0, 5.0))
Geometry.area (Geometry.Circle(1.4))
Geometry.area (Geometry.Square(2.5))

I changed the shape to be a discriminated union because overloading of functions to take different tuples is not allowed.  Instead, I then switched to a union and pattern matched against that, thus giving the value.  Let's move onto more quick examples on how they differ

Lists

Simple list processing is also pretty important.  F# and Erlang are also quite similar in this respect as well.  There are a few things F# doesn't have such as the remove operator, but for the most part, it's pretty comparable.  Functional languages have much different collections than imperative ones, which are optimized for recursion.  This includes the feature of the head, the first item in the list, and the tail, the rest of the list.  Let's look at a simple sum function in Erlang.

-module(MyLists)
-export(sum/1)
sum([H|T]) -> H + sum(T).
sum([])       -> 0.

L = [1,3,10]
MyLists:sum(L)

What I am able to do is pattern match against the head and the tail of the given list to add the head value to the recursive call to the tail through linear recursion.  Next, I'll take that same sample and port it to F# to show how little difference there is.

module MyLists =
  let rec sum = function
    | [] -> 0
    | H::T -> H + sum(T)

let l = [1;3;10;]
let lResult = MyLists.sum(l)

Applying lambda expressions on top of lists is pretty simple as well.  Here is a simple map function on a list in both Erlang and F#.

-import(lists, [map/2]).
L = [2,4,6,8,10].
LResult = lists.map(fun(x) -> x*x end, L).

And then in F#, to be able to do the map:

[2;4;6;8;10] |> List.map(fun x -> x * x)

As you can see, there are some differences, but for the most part, I haven't had any issues jumping between the languages.  This was just meant to be a little exercise about how you can learn from each language.  There is much to be learned from both languages, especially in regards to concurrency.  I hope to cover more of that shortly. 

Wrapping It Up

Functional languages such as Erlang and F# have a lot to offer in terms of concurrency oriented programming.  I think now that Moore's law has changed in a way that standard sequential programming doesn't work as well, it's time to start discovering what the functional programming people and for that matter Erlang people have been talking about.  This is meant to give you just a little kickstart to look at Erlang, and indeed F# for concurrency.  But, not only that, but take the ideas from here and apply them to your other language of choice whether it be C#, Ruby, Python and so on.

The real keys to success for Erlang reside not only in the language itself, but also the frameworks around it, and the tooling, such as the IDEs, etc.  Ruby became popular as a language due to the Rails framework although the tooling still isn't the best for it.  How will Erlang grow in this area remains to be seen, but I am optimistic.

kick it on DotNetKicks.com

No Comments