Freitag, 17. Oktober 2008

Müssen Programme schön sein?

Unter dem Titel "Beautiful Code" erschien Ende 2007 eine Sammlung von Essays exzellenter, erfahrener Programmierer wie Brian Kernighan, Charles Petzold, Jeffrey Dean, Yukihiro Matsumoto, Douglas Crockford u.v.a.m. Jeder präsentiert ein Stück Software oder eine Programmieridee, die er als besonders reizvoll oder schön empfindet.[1] Das Spektrum der verwendeten Programmiersprachen ist gross: C, C++, Java, Haskell, Python, JavaScript, Perl, Ruby und sogar FORTRAN sind vertreten - wie zum Nachweis, dass es in jeder Programmiersprache möglich ist, schön zu programmieren.

Warum bemühen sich Programmierer aber um schöne Programme? Warum begnügt man sich nicht damit, lauffähigen Code zu programmieren? Ist der Code nicht nur ein Zwischenspiel auf dem Weg zum ausführbaren Programm - der Adressat also bloss eine Maschine? Und - da Maschinen keine ästhetische Empfindungen haben, sondern ganz stumpf jeden beliebigen vorgelegten Code ausführen: Ist die Bemühung um schöne Programme daher nicht ein Luxus, eine Zeitverschwendung?

In dieser Argumentation steckt ein Denkfehler. Es ist nicht der Quellcode, den die Maschine ausführt. Die Maschine hat zur Laufzeit mit dem Quellcode des Programms nichts zu schaffen.[2] Der Compiler hat aus dem Quelltext Maschinencode erzeugt. Die Maschine liest lediglich diesen Maschinencode byteweise aus dem Speicher und führt die darin codierten elementaren Operationen - Ein- und Auslesen von Registern und einfache arithmetisch-logische Operationen - der Reihe nach aus.

Wenn man die Programmierung mit anderen Zweigen von Produktentwicklung vergleicht, so muss man zwangsläufig zu dem bereits 1992 von Jack W. Reeves dargestellten Ergebnis kommen: Der Quelltext ist das Design.[3] Damit sollen nicht vorgängig einsetzbare Designtools herabgesetzt werden, die selbstverständlich eine wichtige und nützliche Rolle beim Entwurf von Software darstellen. Aber das definitive Design, das wirkliche Design bleibt der Quelltext. Was in Dokumenten steht, die während der Entstehung der Programme erzeugt wurden, kann veraltet sein. Solche Dokumente können noch Designvorgaben enthalten, die sich als ineffizient oder aus anderen Gründen dysfunktional erwiesen haben und daher bei der Programmierung nicht verwendet wurden. Nicht immer ist noch Zeit übrig, die Dokumente den tatsächlichen Gegebenheiten anzupassen. Wer wissen will, was ein Programm wirklich tut - sei es, weil ein Review durchgeführt wird, sei es, weil er das Programm anpassen oder debuggen muss - der schaut in der Regel in den Quelltext. Denn dieser stellt zuverlässig den aktuellen, produktiven Stand des Programms dar. Der Quelltext dient in erster Linie genau diesem Zweck: Er ist ein garantiert aktuelles Designpapier zur Information anderer Entwickler. Die Aktualität des Designs ist automatisch sichergestellt, da es direkt für die maschinelle Herstellung des Produkts verwendet wird - für den "Build". Im Unterschied zu allen anderen Designpapieren der Welt kann man Programmquelltexte in eine Maschine einspeisen, die daraus direkt das entworfene Produkt erzeugt: Ein ausführbares Programm.

Dass ein Programm den Regeln der Syntax gehorcht, ist aus der Sicht der Programmierer nur eine Rahmenbedingung. Es gehört gewissermassen zu den besonderen Stilregeln beim Verfassen von Programmen und wird durch den Compiler abgesichert. Insoweit die Stilregeln eingehalten werden, ist ein Programm ein frei verfassbarer Text, von Menschen für Menschen. Als Designpapier ist es natürlich zweckgebunden, es dient der Herstellung von Software mit bestimmten Funktionen: Der Programmquelltext ist aber auch ein literarisches Erzeugnis: Man kann ihn vielleicht mit einem Haiku vergleichen, das auch an strenge Silbenregeln gebunden ist, dessen Schönheit gleichwohl jeder Kenner zu würdigen weiss. Der Wortschatz einer Programmiersprache ist sehr beschränkt, die Syntaxregeln sind ausserordentlich streng. Aber es bleiben Freiheiten. Je besser man die verwendete Programmiersprache kennt, umso klarer, effizienter und - schöner kann man sich in ihr ausdrücken.

Manche schaffen es sogar, Haikus in einer Programmiersprache zu schreiben - so der anonyme Student, der während seines Studienabschlusses folgenden Haiku verfasste (er ist auch in Perl 5.8.7 noch frei von Syntaxfehlern!):[4]


study, write, study,
do review (each word) if time.
close book. sleep? what's that?

In Programmier-Poesie wie dieser drückt sich allerdings nicht das aus, was gemeinhin unter schönen Programmen verstanden wird. Die alltägliche Programmier-Ästhetik richtet sich nicht auf zweckfreie Produkte wie dieser Haiku, sondern sieht den Quelltext als eine Kristallisation von Gedanken — Strukturen, Konzepten, Entwürfen, festgehalten in den strikten Regeln der Programmiersprache. Die Schönheit eines Programms ist daher eher mit der Schönheit eines mathematischen Beweises als mit der eines Gedichts zu vergleichen.

Auf den ersten Blick ist es verblüffend, dass das Streben nach Schönheit und Eleganz im Quelltext auch zu besseren Produkten führt: Muss doch das fertige Produkt nur einen Satz von bestimmten erwarteten Funktionen sicher abdecken. Das klingt nicht nach Schönheit, sondern eher langweilig. Aber die Funktionsabdeckung ist nicht alles - es geht auch um die einfache Wartbarkeit und Verbesserbarkeit.

"Wartbarkeit" hat für Software eine Sonderbedeutung. Ein defektes Auto kann man in einer Werkstatt abgeben und bekommt es repariert. Anders bei Software: Einen Softwarefehler meldet man dem Hersteller, der den Fehler zum Anlass nimmt, gleich ein neues Produkt zu entwerfen. Denn jede Änderung des Quelltextes bedeutet eine Änderung des Entwurfs! Wartung und Erweiterung sind daher von der Vorgehensweise identisch: Jede Arbeit der Entwicklung läuft auf eine Entwurfsänderung hinaus. Ich habe dies in meinem Blog Änderbarkeit - Hauptkriterium für Software näher diskutiert. Dass dabei ein Satz von Anforderungen stabil erfüllt bleiben muss und nur durch weitere neue Anforderungen ergänzt wird, gehört wie die Syntax zu den Spielregeln. Syntaxcheck bzw. Modultests legen die statischen und dynamischen Rahmenbedingungen des Programms fest; auf dieser Grundlage entfaltet sich die Kreativität der Entwickler.

Matsumotos Beitrag Treating Code As An Essay (in [1], S. 477ff.) gibt verschiedene Kriterien für schöne Programmtexte. Leitgedanke ist dabei, dass das Arbeiten mit der Software Spass machen soll (so wie dem Anwender die Arbeit mit der Software Spass machen soll):

  • Kürze.- Es ist eine Kunst, etwas kurz auszudrücken und Redundanzen wegzulassen. Die Programmiersprache wie auch die erstellte Software sollten so aufgebaut sein, dass immer nur das für den jeweiligen Zweck Benötigte aufgeführt werden muss.
  • Einfachheit.- Bei aller Kürze sollte der wesentliche Gedanke klar erkennbar und leicht zu verstehen sein.
  • Beständigkeit.- Software hat ihre eigene Szene, ihre Kultur und Tradition. An das Bewährte darin sollte man anknüpfen.
  • Flexibilität.- Software soll für ein möglichst breites Spektrum von (Programmier-)Aufgaben einsetzbar sein. In keinem Fall soll man zur Verwendung von Modulen, Konstrukten oder Parametern gezwungen sein, die man für die aktuelle Aufgabe gar nicht benötigt. Matsumoto nennt diese Eigenschaft Flexibilität, man könnte sie auch Vielseitigkeit nennen.

Die Schönheit des Codes ergibt sich durch eine harmonische, ausgewogene Mischung dieser vier Eigenschaften, so dass die Ausgewogenheit als fünftes Kriterium hinzukommt. Wenn man sich diese Kriterien genauer ansieht, fällt auf, dass sie alle die Änderbarkeit von Programmen erleichtern: Ein kurzes Programm lässt sich effizienter ändern als eines, das länger als nötig ist und somit Redundanzen enthalten muss. Die Einfachheit hilft beim Verständnis des Programmablaufs und macht es natürlich auch einfacher, das Programm zu ändern. Die Beständigkeit kommt einem bei der Wiederverwendung von Software zugute, und die Flexibilität erleichtert das Arbeiten mit dem Programmcode.

Matsumoto's Kriterien umreissen recht gut, was schöne Programme ausmacht, wenn auch nicht umfassend. Meines Erachtens ist aus seinen Kriterien nicht ableitbar, warum beispielsweise ein rekursiver Algorithmus einen so besonderen ästhetischen Reiz hat. Mit dem Hintergrund der besseren Änderbarkeit erklärt sich jedenfalls, warum das Bemühen um Schönheit im Programmcode kein Ästhetizismus ist, sondern einen konkreten, praktischen Nutzen aufweist: Schöne Programme sind auch gute Programme.


[1] Andy Oram und Greg Wilson [Hrsg.], Beautiful Code - Leading Programmers Explain How They Think, o'Reilly, 2007.
[2] Eine Ausnahme bilden hier die dynamisch generierten Programme, in denen programmgesteuert Quellcode erzeugt, kompiliert und ausgeführt wird. Die Überlegungen zur Ästhetik von Programmcode gelten nur dann auch für dynamisch generierten Code, wenn dieser einem Menschen zu Gesicht kommt, beispielsweise weil er in einer Klasse gespeichert wird, die vom Entwickler noch geändert oder angepasst werden kann.
[3] Jack W. Reeves, What is Software Design, The C++ Journal, Herbst 1992.
[4] Larry Wall, Tom Christiansen, Jon Orwant, Programmieren mit Perl, 3. Auflage, o'Reilly, S. 671.

Keine Kommentare :