Live Fast – Die Young

– the story of Erlang Error Handling

I recently had the honor to be guest at the Cofinpro Podcast and we talked about Erlang among other related things. One topic we touched lightly in just one sentence was Erlang’s error handling.

The way an Erlang developer will handle errors and exceptions might surprise other developers. If one writes software in a language like C or Java the developer is used to think about all the possible ways one’s software might fail and handle that failure to prevent crashes.

An Erlang developer will not prevent failure. He will not even think about failure prevention at all. All an Erlang developer will think about is the aftermath of failure and crashes. This post is a first overview of the ways of Erlang’s crash site treatment.

Let It Crash

Before developing software in Erlang I was used to writing software defensively. That means I thought hard about what could go wrong and what should happen instead. The defensive code is littered with checks for arguments and types, with try-catch-finally-frames and log messages.

In most languages working with multiple processes is painful and error-prone. So many programs will not have more than one process. If that process dies from an unhandled error the whole program crashes and leaves the user out in the rain.

So a good developer will test and check and prove that his software works in all possible cases (that one can think of). The result is code that is full of error checking code that is convoluted with the business logic.

In Erlang just let it crash. As simple as that. It is more or less the opposite of defensive programming. Since processes are cheap and in Erlang processes will often be used like objects in other languages an Erlang developer will let the process crash and die. The software that solves the problem will only care about problem-solving. Writing the part the developer will assume that all input will be faultless and failure will not happen.

Let Someone Else Fix It

In the bouquet of processes, an Erlang developer will set up monitoring processes. Those monitors will not contain business logic but they will monitor the health of other processes. If a process crashes and dies it will know what to do with that. This monitoring works across machine boundaries since one cannot make fault tolerant systems on a single machine.

That is the second part of an Erlang software. Next to the problem-solving business logic the failure handling and error-correcting code often is generic so it can be reused in future applications.

In my opinion, this is a nice separation of concerns. Writing code that solves the problem and separating it from code that fixes failures.

For further reading, I recommend Programming Erlang by Joe Armstrong.

Common Lisp: Release your Software

Preface: The following post is about adventure games, Common Lisp and also about seven years old – lost and found in the drafts folder. I still liked it after all this years and therefore published it after all. Have fun.

After porting my adventure game Mork to Common Lisp I searched a way to release and share it to a community.

A Living Being

One truth that occured to me was, that programming in Lisp means interactive  programming. Code is not architected or designed, it’s explored through a interactive interface into the running software. Code is behaviour that is researched by the coder; functions come to existence, they are formed and morph like a Morula.

Though languages like Ruby and Python know such a coding style, too, the interactively  optimised functions will finally be written into a file to become a persistent part of the software.

Lisp is of a different feather. The interactive interface in Lisp is called a REPL – short for Read Eval Print Loop. It does exactly what the naming suggests: it reads user input, evaluates it with its known function context, prints the result and loops to a new prompt to take new input. Most users of a Unix operating system is this a very familiar concept as they use it on a daily basis in form of a terminal application.

In a Lisp REPL the function context is the software that is running. On upstart all connected libraries are loaded into the REPL and build the context. These functions may be updated or extended and new functions will be written. Though one could easily take a function from the REPL into a file and so build a library. But that library would finally be loaded back into the REPL to be executed – so why bother creating a whole bunch of libraries that form a software at all, if one could also persist the status of the REPL and therefore would get the current snapshot of the evolved software as it is?

A software written in Lisp is not unlike a living being. It evolves in a friendly environment and survives through adaptation. The REPL is this friendly environment. Without it, Lisp functions are dead[1] and could also be written on paper for research purposes. But they won’t do anything there.

Pack up the whole world

I thought that it would be nice to wrap the whole REPL in its current state as a snapshot of my work into an executable to share the game; so the later enthusiastic gamer wouldn’t need to know how to setup and start a REPL by themself and load all the needed libraries.

I found a post by esden that helped me out here. It writes that Common Lisp itself provides the needed functionality without the need for an extern compiler. Is the REPL set and are all libraries loaded and the game is in a release worthy state just type

(sb-ext:save-lisp-and-die "Mork" :executable t :toplevel 'main-program-function)

into the REPL. The reader should switch Mork with the designated title of the software. The switch :executable makes the resulting software executable from the operating system so that a user doesn’t have to know that the software is written in Lisp at all. The parameter :toplevel controls the entry point into the software.

This is a very easy way to share your Common Lisp software with others. The target machine doesn’t have to have Common Lisp or any of the libraries installed. It comes as a whole. For very small software this means a large overhead, but for bigger software like a video game this is a rather comfortable way.

__

[1] Lisp files can be compiled. Through compilation a .lisp file becomes a .fasl file. But that cannot be executed. It is a optimised file to be efficient in loading and runtime behaviour.

Testlabor

In den letzten Wochen beschäftige ich mich vor allem mit Ruby und vielen verwandten Themen. Und wer sich mit Ruby (und Rails) beschäftigt, kommt um das Testen seines Codes nicht herum. Da ich seit Jahren ein großer Freund von Test Driven Development (TDD) bin, freue ich mich über die Gelegenheit, tiefer in das Thema einsteigen zu können. Eine Erweiterung zu TDD ist Behaviour Driven Development. Dabei wird nicht mehr länger die Funktionalität eines bestimmten Codeabschnitts getestet, sondern das Verhalten von Code unter bestimmten Bedingungen. Doch dazu später mehr. Heute geht es darum, eine automatisierte Testumgebung, inklusive Growl Notifications aufzusetzen.

Bemerkung: Ich selbst arbeite ausschließlich an Macs, dementsprechend beziehen sich auch alle meine Artikel auf die Arbeit mit OS X (aktuell: Lion), außer sie sind anderweitig gekennzeichnet.

Vorbereitung: Installation von RVM, Ruby und Rails

Ich empfehle sehr stark, zur Verwaltung von Ruby auf dem Mac den Ruby Version Manager (RVM) einzusetzen. Dazu einfach diesen Anweisungen folgen.

Ist RVM einmal installiert und Ruby auf einer aktuellen Version, kann Rails ganz einfach per

sudo gem install rails

installiert werden. Eventuell wird trotz erfolgreicher Installation verlangt, Rails zu installieren. Das passiert vor allem dann, wenn man eine andere Shell als die Bash verwendet (in meinem Fall zsh) und Ruby zwischendurch ein Update erfahren hat. In dem Fall sollte man seine PATH-Variable prüfen.

Schritt 1: rspec

Als Testwerkzeug verwende ich rspec, eine Sprache zum Beschreiben von Spezifikationen. Die Sprache selbst ist Ruby, auch wenn sie auf den ersten Blick anders aussieht. Sie macht sich die Eigenschaft Rubys zu Nutze, anwendungsspezifische Sprachen zu entwickeln (DSL – Domain Specific Language). Zur Anwendung von rspec komme ich in einem späteren Artikel. Hier geht es – wie schon geschrieben – nur um die Installation.

Die Installation von rspec ist denkbar einfach:

gem install rspec

Um rspec anstelle von Unit Testing in einem Rails Projekt unterzubringen, reichen folgende Schritte:

Sollte noch kein Rails Projekt bestehen, wäre jetzt der richtige Zeitpunkt, eines anzulegen.

$ rails new demo-project -T
$ cd demo-project

Der Parameter -T dient dazu, keine Testumgebung zu generieren. Das wollen wir ja hier selbst machen.

Gemfile anpassen:

group :development do
 gem 'rspec-rails'
end
group :test do
 gem 'rspec'
 gem 'webrat'
end

Anschließend das Bundle noch einmal laden:

bundle install

Und rspec für die Anwendung installieren:

rails generate rspec:install

Das Rails Projekt sollte jetzt einen Ordner spec haben, in welchem sich die Tests befinden.

Schritt 1.5: Testumgebung testen

Das folgende Beispiel ist schamlos aus dem Buch “Ruby on Rails Tutorial – Learn Rails by Example” von Michael Hartl     geklaut.

Zum Testen der Umgebung, generieren wir einen Controller:

rails generate controller Pages home contact

Es werden nun ein Controller, verschiedene Views und einige Testdateien angelegt. Da wir aber nicht alle angelegten Tests brauchen, sondern uns in erster Linie der Controller interessiert (wir testen die Views und Heller durch den Controller), können wir den Ordner spec erst einmal aufräumen:

$ rm - r spec/views spec/helpers

Nun kann man seine Installation per

$ rpsec --color spec

testen.

Schritt 2: Tests automatisieren

BDD kann süchtig machen. Vor allem, wenn die Tests vollkommen automatisch im Hintergrund Abläufen und der Entwickler bei jeder Änderung am Code sofort ein Feedback bekommt, wie viele Tests noch fehl schlagen.

Dafür braucht es nur sehr wenige Erweiterungen.

Eine Handvoll Edelsteine …

$ sudo gem install autotest
$ sudo gem install autotest-rails-pure
$ sudo gem install autotest-fsevent
$ sudo gem install autotest-growl

… sowie eine Konfigurationsdatei:

$ vim .autotest
require 'autotest/growl'
require 'autotest/fsevent'

Fertig.

Die Testumgebung kann jetzt über

$ autotest

gestartet werden.

________________________________________

Empfohlene Lektüre:
XP Rules: Test First! (en)
Introducing BDD by Dan North (en)