Die Programmiersprachen Lisp und Smalltalk haben schon einige Jahrzehnte auf dem Buckel. Doch dank engagierter Communitys glänzen sie mit modernen Bibliotheken. Beim Umsortieren von Fußnoten und vor allem bei der Webprogrammierung zeigen sie, was in ihnen steckt.
Das Linux-Magazin hatte seine Programmieraufgaben auch an Entwickler geschickt, die abseits der aktuellen Mainstream-Sprachen arbeiten. Zwei nahmen die Herausforderung an und reichten Lösungen in Lisp und Smalltalk ein, um für ihre Lieblingssprachen zu werben. Vollständige Listings gibt\’s online [1].
Für die Implementierung der Aufgaben in Lisp, genauer in der Ansi-standardisierten Variante Common Lisp (CL), sorgte der 29-jährige Entwickler Marco Baringer (Abbildung 1). Der gebürtige US-Amerikaner studierte in Italien an der Universität Turin Informatik und lebt derzeit in Berlin. Neben Perl, das er zum System-Scripting unter Mac OS X und Linux verwendet, programmiert Baringer ausschließlich Lisp. Sein Geld verdient er mit Lisp-Beratung und -Entwicklung bei der Firma Clozure Associates [2], einer der wenigen reinen Lisp-Consulting-Firmen weltweit.
Je oller, je doller
Die Sprachfamilie Lisp existiert etwa seit 1958, als sich am MIT der Hochschullehrer John McCarthy mit seinen Kollegen an ihre erste Umsetzung machte [3]. Damit gehört diese Sprache, zusammen mit Fortran, zu den ältesten noch im Einsatz befindlichen Programmiersprachen. Heute gibt es eine kleine, aber begeisterte Lisp-Community, die schwergewichtige Industrie-Anwendungen, beispielsweise Flugbuchungssysteme, entwickelt und gleichzeitig unterhaltsame Zeitgeist-Anwendungen wie den Online-Bildeditor Roflbot [4] hervorbringt.
Baringer betreut einige Lisp-Bibliotheken und ist einer der drei Hauptentwickler des Superior Lisp Interaction Mode for Emacs (Slime, [5]), der den GNU-Editor zur integrierten Entwicklungsumgebung für Lisp aufrüstet. Das Gespann Slime-Emacs kommt bei der Arbeit mit Open-Source-Implementierungen wie Clisp oder SBCL als De-facto-Standard zum Einsatz, lediglich einige kommerzielle Lisp-Systeme bringen eigene Tools mit.
Multi-Paradigma
Lisp gibt dem Entwickler mehrere Programmier-Paradigmen an die Hand; für die Fußnoten-Aufgabe des Linux-Magazins hat Marco Baringer hauptsächlich funktional programmiert. Er schrieb zuerst die Funktion »reorder-footnotes-by-order-of appearance«, die die Fußnoten nach ihrem Auftauchen im Text neu nummeriert.
Um die Fußnoten in den eingelesenen Textzeilen zu finden, verwendet er die Regex-Bibliothek CL-PPCRE (Portable Perl-compatible regular expressions for Common Lisp, [5]). Die alte Nummer einer Fußnote zusammen mit ihrem Ersatz speichert er in einer Liste von Paaren. Da die Aufgabenstellung noch eine weitere Interpretation zulässt, programmierte er zudem die Funktion »reorder-footnotes-by-order-listing-order«, die die Verweise nach ihrem Erscheinen in der Sektion »@footnote:« durchzählt. Code, den beide Blöcke verwenden, lagerte Baringer in separate Funktionen aus.
Den Quelltext schreibt der Slime-Programmierer in einem Emacs-Textpuffer, Tastaturbefehle kompilieren und laden den Code. Zum Debuggen dient die interaktive Befehlszeile, die Slime zur Verfügung stellt, REPL (Read-Evaluate-Print-Loop) genannt (Abbildung 2).
Bei der Lösung der zweiten Programmieraufgabe nutzt Marco Baringer einen anderen Ansatz: “Lisp erlaubt mir, nach Wunsch funktional oder objektorientiert zu programmieren”, kommentiert er sein Programm. Er geht von der Datenstruktur aus und schafft zunächst die Klasse »album« mit den benötigten Eigenschaften Titel, Künstler, Jahr und Genre (Listing 1), dazu Funktionen, um Alben anzulegen zu ändern oder zu suchen.
|
Listing 1: Die Klasse |
|---|
01 (defclass album () 02 ((id :type integer :reader id :initarg :id) 03 (title :type (or string null) :initarg :title :accessor title) 04 (artist :type (or string null) :initarg :artist :accessor artist) 05 (year :type (integer 0) :initarg :year :accessor year) 06 (genre :type genre :initarg :genre :accessor genre)) 07 (:metaclass ele:persistent-metaclass)) |
Sprachen nach Wunsch
Im Beispiel der Webanwendung, bei dem HTML-Output gewünscht ist, kommt eine weitere Stärke seiner Lieblingssprache zum Tragen, erklärt Baringer: “Wenn ich Lisp verwende, kann ich im Grunde in jeder beliebigen Sprache programmieren. Es gilt immer die gleiche Syntax mit den bekannten Klammern. Ich kann auch mit geringem Aufwand eine eigene Sprache entwickeln, maßgeschneidert für die aktuelle Aufgabe. Lisp ist die ideale Sprache für Bottom-up-Programming: Man fügt schrittweise Konstrukte zur Sprache hinzu, bis sie zur gewünschten Anwendung passt. Ein Beispiel: Wer in Lisp einen HTML-Template-Mechanismus schreiben möchte, entwickelt Code, der fast aussieht wie HTML und gleichzeitig gültiger Lisp-Code ist. Auf diese Weise braucht er keine HTML-Zeichenketten als Fremdkörper einzubetten, sondern bewegt sich vollständig in Lisp. Genau das hat Edi Weitz in der Bibliothek CL-WHO gemacht [6], die ich für die Web-Aufgabe benutzt habe.”
Listing 2 zeigt CL-WHO im Einsatz. Hier ist eine weitere Lisp-Spezialität zu entdecken, das Makro als Programmcode, der seinerseits Programmcode schreibt. Das Makro »standard-page« in Listing 2 ist eine abstrahierte und wesentlich kürzere Version von Code, der HTML und Programmieranweisungen mischt und den mancher Entwickler möglicherweise in der Skriptsprache seiner Wahl geschrieben hätte. Lisp expandiert Makros vor dem Kompilieren oder beim Debuggen mit den »macroexpand«-Befehlen des Slime-Modus. Allein der expandierte »dolist«-Block würde mehr als 50 Codezeilen umfassen.
|
Listing 2: HTML mit |
|---|
01 (standard-page (:title "Album Listing") 02 (htm 03 (:table 04 (:tr 05 (:th "Title") 06 (:th "Artist") 07 (:th "Year") 08 (:th "Genre") 09 (:th)) 10 (dolist (album albums) 11 (htm (:tr (:td (fmt (title album))) 12 (:td (fmt (artist album))) 13 (:td (fmt (princ-to-string (year album)))) 14 (:td (fmt (description (genre album)))) 15 (:td (:a :href (format nil "edit?id=~D" (id album)) "Edit"))))) 16 (:form :action "list" 17 (:tr 18 (:td (:input :type "text" :name "title" :size 20)) 19 (:td (:input :type "text" :name "artist" :size 20)) 20 (:td (:input :type "text" :name "year" :size 6)) 21 (:td (:input :type "text" :name "genre" :size 10)) 22 (:td (:input :type "submit" :value "Search"))))) 23 )))) |
Als weitere Zutaten für seine Webanwendung verwendete Baringer den Lisp-Webserver Hunchentoot (ebenfalls von Weitz geschrieben) sowie die Datenbank-Abstraktionsschicht Elephant [7], die die Kommunikation mit einer lokalen Berkeley-DB übernimmt.
Smalltalk statt Perl
Randal L. Schwartz hat rund 250 Artikel und zehn Bücher über Perl geschrieben und auch die Programmieraufgabe im Artikel “Babylon 2.0” in diesem Heft mit einem Perl-Skript erledigt. Doch für die zweite Aufgabe setzt er auf die wenig verbreitete Sprache Smalltalk. Der 46-jährige US-Amerikaner erklärt: “Über einen Text gehen, aufsammeln, was man braucht, und es wieder ausspucken – das ist Perls Metier. Ich habe es auch in Smalltalk probiert, aber die String-Verarbeitung dort war nicht so schön. Umgekehrt habe ich mich mit Catalyst, einem Webframework in Perl, bei der Web-Aufgabe schwer getan.” Daher entschied er sich für das Smalltalk-Framework Seaside [8], in dem sich die Webanwendung erstaunlich kompakt umsetzen lässt.
Wachstumschancen
Mit Smalltalk ist Schwartz nach eigenen Angaben bereits in den frühen 80er Jahren in Berührung gekommen. Den Markt für Perl-Schulungen sieht er mittlerweile als gesättigt an, dagegen registriert er bei Smalltalk und speziell Seaside Wachstum. In seinem Blog “Methods and Messages” [9], benannt nach Begriffen des Smalltalk-Jargons, macht er sich für Sprache und Framework stark. Seine Beratungs- und Schulungsfirma Stonehenge [10] führt Seaside in ihrem Angebot.
Smalltalk war 1980 erstmals als Smalltalk-80 verfügbar, mittlerweile gibt es mehrere freie und kommerzielle Implementierungen. Schwartz verwendet Squeak [11], das eine eigene Entwicklungsumgebung mit GUI liefert und unter Apache License 2.0 steht.
Squeak verwendet eine eigene virtuelle Maschine, Squeak-VM. Nur sie unterscheidet sich von Plattform zu Plattform wie beispielsweise Linux, Mac OS X oder Windows. Die VM lädt eingefrorene Smalltalk-Systeme als plattformunabhängige Images, beispielsweise ein System mit Entwicklungswerkzeugen (ihrerseits in Smalltalk umgesetzt) und einen laufenden Seaside-Webserver. Smalltalk gibt dem Entwickler das objektorientierte Paradigma vor. Daher gehört Squeaks Klassenbrowser (Abbildung 3) zum wichtigsten Handwerkszeug des Programmierers. Hier legt er neue Klassen und Methoden an, beispielsweise die Klasse »MusicManager« als Unterklasse einer Seaside-Webanwendung. Ihr fügt er Methoden zum Erzeugen, Suchen und Anzeigen von Einträgen hinzu. »MusicManagerMusic« dient als maßgeschneiderter Datentyp für die Einträge. Wie Abbildung 3 zeigt, braucht sich auch der Squeak-Programmierer bei der Darstellung der Ergebnisse nicht mit HTML-Zeichenketten zu plagen – er benutzt für den Weboutput die Smalltalk-Methoden, die ihm Seaside zur Verfügung stellt.
Speicher-Variationen
Die Musiksammlung speichert Schwartz in einem Smalltalk-Set, das sich rasch auf seine Mitglieder durchsuchen lässt. So spart er sich die Datenbank. Auf Nachfrage nennt er mehrere Optionen für die Datenspeicherung: Für unkritische Anwendungen genügt es nach seinen Angaben, regelmäßig das gesamte Image als Datei zu sichern. Andere Möglichkeiten sind ein objektrelationaler Mapper, der zum Speichern eine SQL-Datenbank einsetzt, oder die Bibliothek Magma, die Objekte auf Dateien abbildet. Für die Enterprise-Klasse schließlich biete die Firma Gemstone das Ablegen der VM in einer Datenbank an – das “Oracle der Smalltalk-Welt”.
Das Distributionsformat für Squeak-Anwendungen sind die komprimierten Monticello-Archive mit der Dateierweiterung »*.mcz«. Sie lassen sich per Drag & Drop in ein laufendes Squeak-System laden. Da sie zudem noch die komplette Historie des ausgelieferten Code enthalten, dient Monticello gleichzeitig als dezentrale Versionskontrolle.
Monticello ist nicht in allen Smalltalk-Implementierungen verfügbar, aber es gibt auch einen traditionellen Weg, Programme weiterzugeben: Der Smalltalk-80-Fileout serialisiert Klassen und Methoden und schreibt den Code in eine Textdatei (Listing 3). Diese lässt sich in fast alle Smalltalk-Systeme laden und erzeugt dort die benötigten Klassen und Methoden – die zahlreichen Anführungszeichen dienen als Trenner beim Einlesen.
|
Listing 3: |
|---|
01 [...] 02 Object subclass: #MusicManagerMusic 03 instanceVariableNames: 'title artist year genre' 04 classVariableNames: '' 05 poolDictionaries: '' 06 category: 'MusicManager'! 07 08 !MusicManagerMusic methodsFor: 'accessing' stamp: 'rls 8/6/2008 14:38'! 09 artist 10 ^ artist! ! 11 12 !MusicManagerMusic methodsFor: 'accessing' stamp: 'rls 8/6/2008 14:38'! 13 artist: anObject 14 artist := anObject! ! 15 16 !MusicManagerMusic methodsFor: 'accessing' stamp: 'rls 8/6/2008 14:39'! 17 genre 18 ^ genre! ! 19 20 !MusicManagerMusic methodsFor: 'accessing' stamp: 'rls 8/6/2008 14:39'! 21 genre: anObject 22 genre := anObject! ! 23 24 !MusicManagerMusic methodsFor: 'accessing' stamp: 'rls 8/6/2008 14:39'! 25 title 26 ^ title! ! 27 28 !MusicManagerMusic methodsFor: 'accessing' stamp: 'rls 8/6/2008 14:39'! 29 title: anObject 30 title := anObject! ! 31 32 !MusicManagerMusic methodsFor: 'accessing' stamp: 'rls 8/6/2008 14:40'! 33 year 34 ^ year! ! 35 36 !MusicManagerMusic methodsFor: 'accessing' stamp: 'rls 8/6/2008 14:40'! 37 year: anObject 38 year := anObject! ! 39 40 41 !MusicManagerMusic methodsFor: 'printing' stamp: 'rls 8/6/2008 19:05'! 42 printOn: aStream 43 aStream 44 print: title; 45 nextPutAll: ', by '; 46 print: artist; 47 nextPutAll: ' in '; 48 nextPutAll: year asString; 49 nextPutAll: ', genre '; 50 nextPutAll: genre asString.! ! 51 [...] |
Der Rails-Killer?
Während einer Seaside-Sitzung steht dem Squeak-Entwickler ein Live-Debugger bei: Tritt ein Fehler auf und klickt der Programmierer im Webbrowser auf den Debug-Button, öffnet sich der Debugger in der Squeak-IDE. Hier kann der Entwickler Änderungen vornehmen und anschließend die Ausführung der Webanwendung fortsetzen, als wäre der Fehler nicht aufgetreten. Dieses Intra-Hit-Debugging hält Schwartz für das Alleinstellungsmerkmal von Seaside – ein Killerfeature, das er besonders gerne Ruby-on-Rails-Entwicklern vorführt, die er für das Framework gewinnen möchte.
|
Infos |
|---|
|
[1] Listings zu diesem Artikel: [ftp://www.linux-magazin.de/pub/listings/magazin/2008/10/lisp-smalltalk] [2] Clozure: [http://www.clozure.com] [3] John McCarthy, “History of Lisp”: [http://www-formal.stanford.edu/jmc/history/lisp/lisp.html] [4] Roflbot: [http://wigflip.com/roflbot/] [5] Emacs-Modus Slime: [http://common-lisp.net/project/slime/] [6] Lisp-Bibliotheken von Edi Weitz: [http://www.weitz.de] [7] Elephant: [http://common-lisp.net/project/elephant] [8] Seaside: [http://www.seaside.st] [9] Blog von Randal Schwartz: [http://methodsandmessages.vox.com] [10] Stonehenge Consulting Services: [http://www.stonehenge.com] [11] Squeak: [http://squeak.org] |








