My Road to Erlang

I had three or four job offers my last semester of college, all of them with telecom companies just north of Dallas. I ended up working for Ericsson in the early 1990s.

Now if you're expecting me to talk about how I hung around with the brilliant folks who developed Erlang...don't. Ericsson's telephone exchanges were programmed in a custom, baroque language called PLEX. Syntactically it was a cross between Fortran and a macro assembler. You couldn't pass parameters to functions, for example; you assigned them to variables instead, much like the limited GOSUB of an 8-bit BASIC. The advantage was that there was a clean one-to-one correspondence between the source code and the generated assembly code, a necessity when it came to writing patches for live systems where taking them down for maintenance was Very Bad Indeed.

The other thing worth mentioning about PLEX and Ericsson's hardware of the time is that they were custom designed for large scale message passing concurrency. That hardware created in the 1970s and 1980s was built to handle tens of thousands of processes certainly makes dual core CPUs seem a bit late to the party.

Ericsson had a habit of periodically sending employees to the mothership in Sweden, and after one such trip my office mate brought back a sheet of paper with a short, completely unintelligible to me, Erlang program on it. In three years at Ericsson, my total exposure to Erlang was about thirty seconds. I left shortly after that, getting back into game development.

In 1998 I started looking at very high level programming languages, because I was in a rut and getting behind the times. Most of my experience was in various assembly languages (6502, 68000, 8086, SH2, PowerPC), C, Pascal, plus some oddities like Forth. The only modern language I was familiar with was Perl, so like everyone else at the time I could write CGI scripts. I wanted to leapfrog ahead, to get myself out of the low-level world, so I looked to functional programming (covered a bit more in the first part of Admitting that Functional Programming Can Be Awkward).

I worked through online tutorials for three languages: Standard ML, OCaml, and Haskell. I had fun with them, especially OCaml, but there were two glaring issues that held me back.

The first was that the tutorials were self-absorbed in the accoutrements of functional programming: type systems, fancy ways of using types for generic programming, lambda calculus tricks like currying. The tutorials for all three languages were surprisingly similar. The examples were either trivial or geared toward writing compilers. At the time I was interested in in complex, interactive programs--video games--but I didn't have a clue about how to structure even the simplest of games in Haskell. There were a few trivial games written in OCaml, but they made heavy use of imperative features which made me wonder what the point was.

The second issue was that I was used to working on commercial products, and there was little evidence at the time that Standard ML, OCaml, or Haskell was up to the task. Would they scale up to programs orders of magnitude larger than class assignments? And more critically, would functional programming scale up? Would I hit a point when the garbage collector crossed the line from imperceptible to perceptible? Would there be anything I could possibly do if that happened? Would lazy evaluation become too difficult to reason about? There was also the worry that Windows seemed to be a "barely there" platform in the eyes of all three language maintainers. The OCaml interpreter had a beautiful interactive shell under MacOS, but the Windows version was--or should have been--a great embarrassment to everyone involved.

Somewhere in this period I also took a hard look at Lisp (I was one of the first registered users of Corman Lisp) and Erlang. Erlang wasn't open source yet and required a license for commercial use. The evaluation version still used the old JAM runtime instead of the more modern BEAM and was dog slow. It also had the same dated, cold, industrial feeling of the systems I used when at Ericsson. I put it aside and kept tinkering elsewhere.

But I came back when the move to open source occurred. Here's why:

I found I had an easier time writing programs in Erlang. I was focused entirely on the mysterious concept of writing code that didn't involve destructive updates. I wasn't distracted by type systems or complex module and class systems. The lack of "let" and "where" clauses in Erlang makes code easier to structure, without the creeping indentation caused by numerous levels of scope. Atoms are a beautiful data type to work with.

That the tools had been used to ship large-scale commercial products gave me faith in them. Yes, they are cold and industrial, and I started seeing that as a good thing. The warts and quirks are there for a reason: because they were needed in order to get a project out the door. I'll take pragmatism over idealism any day.

Besides being useful in its own right, concurrency is a good pressure valve for functional programming. Too difficult to puzzle out how to make a large functional program work? Break it into multiple smaller programs that communicate.

Speed was much improved. The BEAM runtime is 3x faster than JAM. When I started looking at different languages, I was obsessed with performance, but I eventually realized I was limiting my options. I could always go back to the madness of writing assembly code if I cared that much. Flexibility mattered more. The 3x improvement pushed Erlang from "kinda slow" to "good enough."

I've been using Erlang since 1999, but I hardly think of myself as a fanatic. I still use Perl, Python, C++, with occasional forays into REBOL, Lua, and Forth, plus some other special purpose languages. They all have strengths and weaknesses. But for most difficult problems I run into, Erlang is my first choice.