Friday, May 30, 2008

Erlang is interesting

Late last summer, I picked up Joe Armstrong's Programming Erlang, after having gone from "having heard the name" to hearing the tub thumped -- even if that thumping offered faint praise in its title. But that alone made it the most obvious functional language to try out, as another paradigm shift after having done Python and Ruby.

So I took the book as holiday reading for while cycling through Suffolk (pdf sample, previous edition). And didn't do anything with it after.

Partly this was because work was going into crunch mode, where it stayed up to a couple of weeks ago, partly because I have enough other items in my hobbyist queue, and even then, I mainly do stuff I want to use, which tends to mean local apps.

During the latter part of the autumn, one of the unplanned bits of work I ended up doing at short notice was putting together a simple protocol terminating proxy, for circumstances when the pre-existing Apache-based solution was just too heavy-weight; and for other reasons, a .Net based approach had been ruled out. So what I ended up doing could be termed classic code-reuse, fitting together existing bits of 'C' and C++ code, and tweaking to fit (“And here is one I prepared earlier…”).

But all the time I was doing it, I was thinking that a piece of concurrent, high-reliability code would be so much easier done in a language made for the purpose. For one thing, it would not require spending a good 2/3 of the time just appeasing the necessary Windows APIs; and for another, a functional approach would simplify the handling of the protocol framing and parsing required.

But it worked (after the initial round of silly bugs got cleared out), and proved more robust and capable than I had dared hope. And finally it shipped.

Still, I wasn't satisfied. It could have been better.

Taking up a backlog of self-directed training time, I started from the ground up in Erlang, and as my very first piece of coding in the language (beyond 1+2 -> 3 at the command-line sort of things), put together in about a day and a half, the easy 50% of the proxy -- something that had taken a week when fitting together pre-existing code in a language that I consider myself fluent with, and using familiar APIs.

What's more, it even behaves better under stress tests -- Erlang's {active, once} mode for receiving sockets makes the business of traffic throttling simple a one-liner, so flow is smoothed out and not bursty (better behaved, even, than an equivalent proof-of-concept C# implementation using asynchronous reads).

While it might not be the language for file I/O with big files, for network I/O intensive proxying of a single connection, it does just fine.

The interesting thing about writing this app -- about 200 lines total -- is that the language makes conventional coding idioms look ugly. It looks much nicer to break out that nested if clause into a separate function, where part of the work is done in the function's argument list -- even if it only gets called from one place.

And the application is one which does play to Erlang's strengths beyond the functional nature -- lightweight processes, immutable values, message passing, dynamic typing. From the little I've done so far with F#, it would be harder work (for me at least) to manage the same power/line of code or per man-hour.

No comments :