In der Unix-Welt gibt es ein nützliches Programm namens du (disk usage). Es zeigt einem innerhalb eines gegebenen Verzeichnisbaums an, wieviel Platz jeweils jedes Unterverzeichnis auf dem Datenträger einnimmt. Leider sortiert es die Liste nicht, so daß es nicht leicht ist, die größten Platzverschwender auf einen Blick auszumachen.

Einst baute ich mir einen Shell-basierten Wrapper um es herum, der genau das tat. Dann kam ich auf die Idee, einmal zu testen, wie schwierig es wäre, etwas Vergleichbares in einer „richtigen“ Programmiersprache zu schreiben. So entstand du.cl, eine Common-Lisp-Version des Wrappers.

Als sie fertig war, stellte ich fest, daß ich für die Umsetzung bereits einiges an Techniken benötigt hatte: Stringverarbeitung (Auseinanderpflücken und Wiederzusammensetzen), Aufruf von Unterprozessen, Kommunikation mit diesen über Pipes, Verarbeitung und Sortierung von (in geringem Maße) komplexen Listen. Dennoch war der Code nicht lang oder kompliziert geworden.

Das brachte mich auf den Gedanken, daß es sich bei diesem Programm um einen passenden zweiten Schritt nach dem guten, alten „Hallo-Welt-Programm“ handeln könnte: Niedrige, aber vorhandene Komplexität, geringer Programmieraufwand und dennoch die Lösung eines konkreten, realen Problems. Gerade Letzteres ist sehr nützlich, um zu evaluieren, wie praxistauglich eine Programmiersprache und ihre Compiler sind: Denn so elegant und schön eine Sprache sein mag — wenn man damit nicht in der Lage ist, ein Alltagsproblem zu lösen, beschränkt das ihre Nützlichkeit bereits in vernehmlichem Maße.

Auch die Qualität der Dokumentation stellt sich schnell heraus, wenn man gezwungen ist, die nötige Funktionalität darin zu suchen. Allein das Aufrufen eines Unterprogramms mit Umleitung der Pipes ist häufig bereits etwas, das man nicht auf Anhieb in den Bibliotheken findet.

Möglicherweise (vermutlich aber eher weniger) ist du.cl auch brauchbar, um sich schnell einen Überblick über den Teil einer Programmiersprache zu verschaffen, der nichts mit Komplexitätsmanagement zu tun hat. (Abstraktere Konzepte wie Klassen und Methoden zum Beispiel sind auf dieser niederen Ebene natürlich unpassend.) Freilich sagt das noch sehr wenig darüber aus, wie sich die Sprache in einem größeren Unterfangen schlägt, doch ist es immerhin ein interessanter Aspekt.

Im Laufe der Zeit haben sich einige Implementierung der du.cl angesammelt, manche davon auf Rechnern, die ich nicht mehr verwende (ironischerweise unter anderem die ursprüngliche du.cl selbst, so daß ich jetzt nur noch Implementierungen besitze, die andere Dateiendungen haben). Ich habe auch derzeit nicht gerade die Motivation, diese alten Versionen herauszusuchen. Dennoch: Diejenigen Implementierungen, die ich gerade zur Hand hatte, habe ich unter http://matthias.benkard.de/code/ducl/ ins Netz gestellt. Sie sind nicht unbedingt idiomatisch, da ich die jeweiligen Sprachen nur zum Teil beherrsche und es sich teilweise um meine ersten Experimente mit ihnen handelt. Wen aber grundsätzlich interessiert, wie man in Io, Factor und SWI-Prolog Unterprozesse aufruft und ihre Ausgaben verarbeitet, kann sich den Code ansehen.

Update 3.5.2010: JavaScript.

Update 3.5.2010 #2: Die ursprünglichsten Varianten wieder ausgegraben: Common Lisp, Haskell, O'Caml, PLT Scheme.

Update 15.4.2010: C++.

Update 23.11.2012: Rust.

Update 31.3.2013: TypeScript, Rust 0.5.

Update 7.4.2013: Scala.

Update 5.5.2015: Perl 6.

Update 1.6.2018: Rust 1.26.

Derzeit vorhandene Implementierungen
C++du.cpp
Common Lisp (ECL)du.cl
Factordu.factor
Haskell (GHC)du.hs
Iodu.io
JavaScript (Narwhal)du.js
Objective Camldu.ml
Perl 6du.p6
Prolog (SWI)du.prolog
Rubydu.rb
Rust (v0.5, 2013)durst.rs
Rust (v1.26, 2018)durst-2018.rs
Scheme (PLT)du.ss
Scala (2.10)DU.scalaDU.jar (kompilierte Version)
TypeScript (Node)du.ts