Zwischen Papageien und Bibliotheken
Artikel erschienen in Swiss IT Magazine 2005/13
Ursprünglich wurde Perl als eine Art erweiterte Shell entwickelt und sollte die Vorzüge von Tools wie sed, awk, lex oder (e)grep vereinen. Die Ende 1987 von Larry Wall veröffentlichte Version 1.0 war denn auch tatsächlich nicht viel mehr als eine erweiterte Shell. Seit Version 4 hat Perl dann Einzug auf vielen Unix-Systemen gehalten und war unter der GPL beziehungsweise der von Larry Wall entwickelten Artistic License als Open Source verfügbar. Mit Version 5 wurde die Programmiersprache endgültig erwachsen. Der Sprung von 4 auf 5 war der bisher grösste Schritt und brachte wichtige Neuerungen mit sich. Doch nun steht Version 6 vor der Tür, und die Sprache Perl soll wiederum tiefgreifende Veränderungen erfahren.
Perl 5 war im wesentlichen ein Rewrite des Codes durch Larry Wall. Mit Perl 6 sollte dies anders werden: Nicht mehr Larry Wall, sondern die Perl Community sollte die Spezifikationen entwickeln und die Implementierungen für zukünftige Versionen gestalten. Der Code von Perl 5 war sehr schwierig zu pflegen, und so drohte Stagnation bei der Weiterentwicklung. Auch waren manche Konzepte in Perl 5 nicht bis ins letzte ausgereift, was vor allem das objektorientierte Programmieren betraf. So war in Perl auch vieles möglich, was in einer «sauberen» Programmiersprache nicht möglich sein darf. Also entschloss man sich zu einem erneuten Rewrite des Codes. Perl 6 ist aber mehr als nur ein Rewrite – auch die Sprache selbst sollte einige Neuerungen erfahren. Deshalb haben Larry und seine Mitstreiter aus der Perl Community beschlossen, dass Perl sauberer, schneller (durch Einführung einer Virtual Machine) und einfacher benutzbar werden muss. Vieles wurde aus Perl 5 übernommen, manches verbessert und Vermisstes sollte hinzugefügt werden.
Aber nicht nur das Design von Perl sollte erneuert werden. Perl ist bislang eine interpretierte Programmiersprache. Das heisst, dass der Programmcode als Source vorliegt. Der Perl-Interpreter lädt den Code, überprüft ihn und führt ihn dann aus. Dadurch ist Perl oft als etwas träge verschrien. Doch das soll sich nun ändern.
Perl soll zukünftig – ähnlich wie Java – auf einer virtuellen Maschine laufen. Eine virtuelle Maschine bildet eine Art Rechner im Rechner ab. Diese führt im Gegensatz zum Interpreter nicht den Source Code «direkt» aus. Vielmehr muss der Source Code vorab in einen Maschinencode (Bytecode) übersetzt werden. Erst dieser wird von der Virtual Machine geladen und ausgeführt, womit das Prinzip sehr ähnlich zu Compiler-Sprachen wie C oder C++ ist. Aber anders als die Compiler, die direkt auf die Hardwareplattform zugeschnittenen Maschinencode erzeugen, ist der Bytecode portabel. Das heisst, dass ein auf Solaris erzeugter Bytecode unter Mac OS genauso lauffähig ist. Das Programm muss also nicht auf jeder Plattform neu kompiliert werden. Es genügt, wenn man einmal den Bytecode-Interpreter – eben Parrot im Falle von Perl oder die Java Virtual Machine (JVM) bei Java – auf der Zielplattform zur Verfügung stellt. Parrot wurde zwar speziell für Perl 6 entwickelt, ist aber so konzipiert, dass er verschiedene dynamische Sprachen wie Python, Ruby, Lisp oder Scheme ausführen können wird. Interessant ist auch, dass es einen Proof-of-Concept gibt, einen Compiler zur Transformation von Java-Bytecode in Parrot-Bytecode zu realisieren.
Die Definition von Parrots Register-Maschine, die sozusagen die «virtuelle CPU» darstellt, ist sehr sauber gehalten und bietet einen umfangreichen Befehlssatz. Programmieren mit PASM (Parrot Assembler) bietet einen interessanten Mix an Features: Zum einen ist es möglich, maschinennahe Instruktionen wie Branches, Jumps, direkte Manipulation der Register oder des Stacks der virtuellen Maschine zu realisieren. Eben «echtes» Assembler wie man es von der Programmierung auf «echten» CPUs kennt. Zum anderen wurden Hochsprachen-ähnliche Befehle und Instruktionen integriert – etwa die Definition von lexikalischen oder globalen Variablen, Objekte, eine Garbage Collection, Continuations, Co-Routinen und noch vieles andere mehr. Dabei wurde aber trotzdem auf eine klare und einfache Syntax Wert gelegt.
Designtechnisch bietet die Sprache Perl 6 einige wesentliche Neuerungen im Vergleich zu ihrem Vorgänger. So liegt eine der grössten Änderungen in den jetzt schon mächtigen Bibliotheken für reguläre Ausdrücke (Regular Expressions), die auch einen neuen Namen bekommen sollen: Ausdrücke heissen in Zukunft «Regeln» (Rules). Aufzählende Charakter-Klassen wie [a-zA-z] werden in Zukunft als [a-zA-Z] notiert. Negierungen (Zeichen XY soll nicht vorhanden sein), die bisher als [^XY] dargestellt wurden, werden zu [XY]. Generell werden in spitzen Klammern in Zukunft sogenannte Assertions definiert. Eine Assertion ist ein Zustand, der je nach Inhalt der Klammern entweder wahr oder falsch sein kann. Die Ausdrücke können alle Arten von Variablen (auch Arrays oder Hashes) oder Code-Abschnitte beinhalten. Der Lesbarkeit dienlich sind Änderungen bei Matches, wenn Optionen dem Match nachgestellt werden. Ein Ausdruck wie m/rabea/i, welcher sowohl rabea als auch RaBEa matcht, wird in Zukunft als m:i/rabea/ geschrieben. Um Multiline Matches zu vereinfachen, wurden zusätzliche Metacharakter eingeführt: Ein ^ matcht den String-Anfang und $ das String-Ende. Entsprechend dazu existieren nun ^^, welches den Zeilenanfang matcht, und $$ für das Zeilenende.
Auch Liebhabern von objektorientiertem Programmieren bietet Perl 6 einige Neuerungen zu bereits Bestehendem. Das neue Perl kennt nun Klassen, Methoden und Mehrfachvererbung, zudem die Attribute «private» und «public», Konstruktoren und Destruktoren. Bedingt dadurch unterscheidet man nun zwischen Funktionen und Methoden. Methoden gehören zu Klassen, Funktionen können überall definiert werden. Funktionen sind nur mehr innerhalb einer Klasse aufrufbar und können auch nicht vererbt werden. Sogar Polymorphismen kennt Perl nun. Durch das Schlüsselwort «multi» kann eine Funktion mehrfach unter demselben Namen definiert werden, allerdings mit unterschiedlichen Parameter-Listen – Java oder C++ Programmierer kennen dies bereits.
multi method plus (Int $a, Int $b) {
$a += $b;
return $a;
}
multi method plus (String $worta, String $wortb) {
$worta ~= " " . $wortb;
return $worta;
}
Auch im prozeduralen Bereich hat sich einiges getan. So wurde Perl um eine Switch-Anweisung erweitert:
given $farbe {
when 'Rot' { print "Rote Rosen
kosten das doppelte\n"; }
when $_ ~~ 'blau' { print "Blaue
Rosen führen wir nicht\n"; }
default { print "Wir suchen besser
eine Farbe für Sie aus\n"; }
}
Weitere Änderungen an Perl 6 wurden auf Wunsch der Community angebracht. So wurden Referenzen in Perl 6 an häufig gemachte Fehler angepasst: Schrieb man in Perl 5 noch $element = $liste[$y] oder $element = $hash{$key} wird man in Zukunft $element = @liste{$y} und $element = %hash{$key} schreiben. Die alte Syntax bekommt eine neue Bedeutung: Aktuell erhält man das fünfte Element einer Liste mit $liste->[5], künftig wird man dafür $liste[5] schreiben. Referenzen auf einen Array oder Hash werden in Perl 6 mit $hashref = %hash; oder $arrayref = @array; gesetzt. Die alte Notation (etwa $arrayref = \@array) bleibt aber gültig. Diese kurze Zusammenfassung von einigen der Neuerungen, die Perl 6 bringen wird, ist bei weitem nicht vollständig. So wird auch ein erfahrener Perl-Programmierer kaum darum herumkommen, sich in Perl 6 neu einzulesen. Dies dürfte aber nicht allzu schwerfallen, schliesslich sind alle Neuerungen sehr eingängig und logisch, womit einem Umstieg keine grossen Hürden in den Weg gesetzt werden.
Wichtig für Entwickler ist, dass es einen sauberen und klaren Migrationspfad von Perl 5 nach 6 geben soll. So sind Tools in Vorbereitung, mit denen man (fast) jeden Perl-5-Source-Code nach Perl 6 transformieren kann. Auch kennt Perl 6 einen Kompatibilitätsmodus, mit dem man Perl-5-Code direkt ausführen können wird. Perl 5 wird weiter gepflegt, und viele der Neuerungen sollen noch in die geplanten Versionen 5.9 oder 5.10 einfliessen. Inkompatible Features können dann über einen Schalter («use Perl 6ish;») de- beziehungsweise aktiviert werden. Umgekehrt kann man auch später mit dem Perl-5-Parser, den es für Parrot auch noch geben wird, seine alten Programme weiterhin verwenden.
Gemäss Zeitplan ist mit der ersten offiziellen Perl-6-Version noch im 3. Quartal 2005 zu rechnen. Der erste Design-Snapshot von Perl 6, auf dem dann die erste Implementierung basieren wird, wurde Ende 2004 gemacht.
Gregor Longariva (longariva@softbaer.de) ist Solaris-Administrator am Rechenzentrum der Universität Erlangen-Nürnberg und Spezialist für die Unix-Betriebssysteme HP/UX, Irix, Linux, OpenBSD und Solaris.