Parkour oder Le Parkour (fälschlicherweise auch Parcours, Parcour oder Parkours bezeichnet) ist eine von David Belle begründete Sportart, bei welcher der Teilnehmer – der Traceur (französisch: „der den Weg ebnet“ oder „der eine Spur legt“) – unter Überwindung sämtlicher Hindernisse den kürzesten und effizientesten Weg von A zum selbstgewählten Ziel B nimmt. Dann gibt es noch das Parcouring. Parcouring wird z. B. bei Veranstaltungen vorgeführt und es ist eine Art Wettkampf im Le Parkour. Es werden künstliche Hindernisse aufgestellt, die der Traceur möglichst schnell überwinden muss.
Dieses Zitat aus Wikipedia trifft durchaus auch auf die Vielfältigkeit im .NET-Framework zu. Manchmal funktioniert alles einfach, manchmal eben nicht so einfach. Manchmal sind Probleme von Natur aus da, durch das Framework gegeben. Manchmal schaffen wir sie uns selbst indem wir nicht Zeitgemäß programmieren, wie es unter anderem Ralf Westphal und Stefan Lieser mit dem Clean Code Developer als Gegeninitiative beschreiben. Probleme und Fehler scheinen unbezwingbar und dennoch überwinden wir sie tagtäglich.
Aber wie tun wir dies, etwa auf direktem Weg? Im Laufe der letzten Jahre hat sich auf der Microsoft Basis eine stattliche Anzahl an Sprachportierungen und Neuentwicklung auf den Weg gemacht die Probleme mit verschiedenen Ansätzen zu lösen. Die Beliebtheit bricht anscheinend nicht ab und nimmt im Gegenteil sogar noch zu, nicht zuletzt auch durch den enormen Einsatz von Novell und dem Entwicklerteam, auf dessen Plattform MONO die Sprachen ebenfalls lauffähig sind. Somit will ich einige Exoten und potente Kandidaten in einem kurzen Rundlauf darstellen, die in Fachzeitschriften wie der dotnetpro in der Ausgabe 02/2009 als Schwerpunktthema zur Ansprache kommen.
Warmup
Dann wollen wir uns doch mal kurz unseren Common Language Runtime Parkour betrachten: Portierungen, Neuentwicklungen, Compiler, Interpreter, Funktional, Objektorientiert, Imperativ. So ziemlich alles was Rang und Namen hat tummelt sich mittlerweile in der CLR, beziehungsweise der kommenden Tocher DLR. Ob bekannte Skriptsprachen wie Python, die zunehmend immer beliebter werdende Ruby, oder ganz alte wie Lisp (hier vertreten durch IronScheme). Es gibt kaum eine Sprache, die es noch nicht in irgend einer Form auf die gemeinsame Plattform geschafft hat. Warum aber jetzt eine Übersicht über diese Sprachen. Vor allem deswegen, da sich die Releases der Sprachen stabilisiert haben, oder dies in Kürze tun werden und Release Candidates der ersten oder zweiten Versionen absehbar sind.
Die Traceurs stellen sich vor
Alleine die Aufzählung aller würde schier den Umfang Sprengen und somit konzentriere ich mich auf ein paar wenige die mir so im Laufe der Zeit aufgefallen sind. Hier will ich nur einige kurz auflisten, von denen ich dann den ein oder anderen etwas beleuchte.
- Boo
- IronPython
- IronRuby
- Phalanger (Php auf der DLR)
- IronScheme
- F#
- Nemerle
- Vulcan.NET
Einzig eine vernünftige, vorzeigbare ECMAscript Implementierung wie sie Java- oder ActionScript darstellt ist mir so, wie ich sie mir vorstelle nicht über den Weg gelaufen.
Der Fuchs sprintet los
Die ersten sechs Sprachen werden den meisten wahrscheinlich noch etwas sagen. Aber mit Vulcan.NET können denke ich die wenigsten etwas anfangen. Warum liste ich diese Sprache dann auf? FoxPro ist vielen vielleicht noch geläufig. Ja, das war die Programmiersprache, die Microsoft mit dem Visual Studio damals mit installiert hat. Persöhnlich habe ich damit knapp 10 Jahre Erfahrung Sammeln dürfen. Nicht immer als aktiver Entwickler von FoxPro-Code, sonder meistens als Konsument der Datenbank über ein 3rd Party Bibliothek. Als dBase Derivat brachte FoxPro eine erstklassige Datenbankintegration, die zu Zeiten von Access seines Gleichen gesucht hat. Im Anbetracht der damaligen Lizenzkosten für einen SQL Server bei einem Vergleich von Leistung pro Zugriffszeit mehr als nur eine gute Alternative. Lange Zeit stellte FoxPro ein gute Lösung für Datenintensive Anwendungen dar. Versprochen wurde eine Weiterentwicklung und Zusammenarbeit mit dem .NET Framework, doch leider steht die Sprache seit 2007 offiziell vor dem aus.
Die letzte angekündigte Erweiterung von Microsoft trug den Namen Sedna und wurde als ServicePack 2 unter den Entwicklern verteilt. Seitdem lebt der Fuchs auf Codeplex unter anderem durch Community Projekte wie VFPX weiter. Auf das .NET Framework hat es der FoxPro Bytecode nie geschafft. Naja fast! Denn mit Vulcan.NET steht eine xBase basierte Sprache bereit die syntaktisch mit Visual Objects gleich zieht, aber dennoch einige Änderungen im Vergleich zu FoxPro mitbringt. Für alle Füchse die ihr Wissen nicht ganz wegwerfen wollen sei ein Blick auf Vulcan.NET empfohlen.
Der Kampf der Schwergewichte
Die meisten Iron-Implementierung sind vermutlich schon jedem .NET Programmierer bekannt, da sie durch Jim Hugunin als Vater von IronPython Einzug in die Microsoft Welt gehalten haben. Er war es auch der mit Jython die Python Console auf der Java-Plattform zum laufen brachte. Ursprünglich als Beweis gedacht, dass .NET nicht leistungsfähig genug sei eine Skriptsprache wie Python zu stemmen, machte er sich daran dies zu beweisen. Erstaunt war er allerdings, als er feststellte dass diese Plattform sehr wohl dafür geeignet sei und nach einigen Optimierungen sogar noch schneller als der ursprüngliche Mitstreiter ist. MS wurde auf ihn Aufmerksam und baute um ihn herum das DLR Team. Eine zukünftige Erfolgsgeschichte, die nicht weiter erzählt werden muss, zielt doch das nächste Framework 4.0 und das Visual Studio 2010 genau auf die DLR. Das Visual Studio 2010 wird vollmundig als neues VS6 angepriesen, das seinerseits als es herauskam beachtliche Leistungen und
Funktionen zeigte. Wie geht es also weiter mit den Iron Implementierungen? Seit Hugunin Python portiert hat stehen die vier Buchstaben IRON als Synonym für die robusten Portierungen von bekannten Sprachen auf der zukunftsweisenden DLR. Ein weiteres Beispiel daüfr sind IronRuby und IronScheme. Eine Skriptsprache, die auch noch schneller sein soll als es das Vorbild ist? Wie es scheint letzten Endes doch eher ein Leichtgewicht - also alles andere als eisern und schwer.
Die Geisterstunde schlägt
Boo schickt sich, von allem ein bischen mit zu bringen und kann darüber hinaus eigentlich mit ganz anderen Merkmalen punkten. Der kleine, gute Geist vereint Mechanismen einer ausgezeichneten Meta-Programmiersprache, die Bestandteile wie abstrakte Syntaxbäume und andere Schmankerl, wie Makros mit sich bringt. Wer da an die define Statements aus C zurückdenkt sollte sich aber deshalb nicht gleich erschrecken auch wenn es vielleicht gespenstisch klingen mag. Diese Features erlauben es dem geneigten Anwender die Sprache um eigene Syntax zu erweitern. Eine Erweiterung des eigenen Sprachumfangs als funktionaler Aspekt - Programmiersprache für Programmiersprachen? Als ausgemachtes Ziel können wir hier wohl eindeutig die Domain Specific Languages ansehen, die mit Boo erstellt werden wollen.
Der Zauberer kommt ins Spiel
In der Riege der Neuentwicklung stich meiner Meinung nach ein Kandidat besonders für die breite Masse der Entwickler hervor: Nemerle ist ein Hybrid und macht den Versuch die verschiedenen Programmierwelten richtig miteinander zu verheiraten. Den Name hat die an der Universität Breslau entwickelte Sprache übrigens von dem Erzmagier "Nemmerle" aus "Der Magier der Erdsee". Die Vereinigung der Welten versucht zwar auch F#, stellt dabei aber eine erstklassige Funktionale Sprache dar. Nemerle hingegen versucht den umgekehrten Weg und will mit C# ähnlicher Syntax funktionale Aspekte besser Umsetzen, als dies mit Lambdas und der Spracherweiterung LINQ der Fall ist. Ob das gelingt und wie erfolgreich dieser Versuch sein wird, muss die Zukunft zeigen. Nicht zuletzt, da viele Firmen vor dem Einsatz von Technologien zurück schrecken, bei denen die Zukunft ungewiss ist. Und diese wird sie für viele bleiben, solange Microsoft sie nicht mit ins Visual Studio Boot holt.
Hoch-Runter? Runter-Hoch?
Im Gegensatz zu imperativen oder objekt-orientierten Sprachen wie z.B. C und C++ mit einem Bottom-Up Ansatz, bei denen zu gegebener Hardware passende Software mit vorhandenen Mitteln erstellt wird, stehen die Funktionalen Programmiersprachen. Als sich damals findige Wissenschaftler aufmachten etwas zu beweisen stand im Vordergrund stand das Konzept, die Algoryhtmen, die Beweißbarkeit. Stück für Stück hat sich im Top-Down Verfahren ein Paradigma entwickelt, das wohl im Moment an der Schnittmenge zwischen den Welten steht. Die Hardware ist mittlerweile leistungsstark genug geworden. Die Algorithmen haben sich weit genug entwickelt um sich auch auf einem Desktop Rechner auszutoben. Und das Moorsche Gesetz wird durch Mehrkernprozessoren bekämpft. Es werden also Muster notwendig, die paralleles Ver- und Abarbeiten unterstützen. Komplexe Probleme, und Parallelverabeitung ist alles andere als trivial, benötigen entsprechende Werkzeuge oder Bibliotheken um von der breiten Masse benutzt werden zu können. Funktionale Programmierung bietet solche Möglichkeiten (siehe Wikipedia).
Die Zwischenbilanz
Gehen wir mal ein paar Schritte zurück und betrachten das Spektakel aus einer gewissen Entfernung. Können wir etwas signifikantes beobachten? Fest steht jedenfalls, dass F# und IronPython/IronRuby durch Silverlight, bzw. Visual Studio 2010 und demnach durch die bereits genannte Microsoft-Unterstützung sehr gute Aussichten für die Zukunft hat. Jetzt muss der Nutzen nur von der Entwicklergemeinde erkannt werden und entsprechend Anklang finden. Frameworks wie Rails für Ruby haben dem Entwicklern gezeigt, wie einfach Programmierung in Verbindung mit einer Skriptsprache und dem Scaffolding sein kann. Nach Vorbild des Prototypen Verfahren wird in Windeseile eine ansehnliche Applikation erstellt. Gesichert wird das Verhalten der untypisierten Sprache durch Komponententests nach den Prinzipien von TDD oder BDD. Mit ASP.NET MVC steht ein .NET Pendant dazu in den Startlöchern, dass die gleiche Funktionalität bietet. Sieht man in die Roadmap von ASP.NET und auch Silverlight, stehen da Punkte zur Implementierung von dynamischen oder funktionalen Sprachen.
.NET wird mit Version 4.0 und seinen Sprachveteranen C# und VB.NET so dynamisch, wie es auch von anderen Vertretern des Interpreterlagers nicht hätte besser gemacht werden können. VB bekommt seine untypisierte Funktion wieder zurück, bei der ein einfaches Dim genügt und C# bekommt das DynamicObject und das Schlüsselwort dynamic. Zudem geht dann mit F# der erste funktionale Player ins Rennen. Ob es ein Big Player wird ... ich wage eine kleine Prognose abzugeben. Nach einigen Diskussionen mit Ralf Westphal bin ich auch der Meinung, dass dies für spezifische Probleme sicherlich zustimmen mag. Aber in seiner Gesamtheit?
Wichtiger sind für mich eher Kandidaten wie Boo oder Nemerle auf der einen Seite, die wichtige Sprachmuster wie Traits (ähnlich den C++ Templates), Mixins, oder Closures wie sie auch genannt werden, bereitstellen. Michael Feathers hat Ende letzten Jahres seine Wunschliste für die nächste Mainstreamsprache bekannt gegeben, der ich sofort zustimmen musste. Echte Komponentenfähigkeit! C# Stünden die Möglichkeiten von echtem wiederverwendbaren Code, wie sie durch eben diese Techniken zur Verfügung stehen gut. Auf keinen Fall wird dies durch eine Mehrfachvererbung wie bei C++ eingeführt werden. Dessen sind wir uns und vor allem die Designer von C# bewußt. Bei F# steht das Schlüsselwort mixins z.B. schon als reserviertes Schlüsselwort in der Pipeline für die zukünftige Entwicklung. Bleibt zu hoffen, dass wir hiervon in Zukunft noch mehr sehen.
Zu zweit ist man weniger alleine
Die Parallelität, in aller Munde Concurrency genannt, wird eine wichtige Rolle spielen. Die durch die Intel GmbH betriebene Seite http://www.software-dev-blog.de/ mit dem Reporter und Autor Michael Hülskötter berichtet Neuigkeiten rund um die Multicore Programmierung. AMD und Intel, um bei den Chipherstellern zu bleiben, sind bei Vier-Kern-Prozessoren angekommen. IBM steht mit dem Cell schon länger bei einer achtkern CPU. Prominentester Vertreter aus der Öffentlichkeit ist hier wohl die Playstation 3. Die parallele Verarbeitung von Anweisungen bei gleichzeitigem Zugriff auf Resourcen bleibt einem scheinbar nur über den mühevollen Umweg der Synchronisierung übrig. Ein heikles Thema, wenn man in dieser Disziplin die Erfahrung der letzten zwei Jahrzehnte betrachtet. Das Unterfangen kann schlichtweg in den bekannten Problemen enden. Deadlocks, schlecht wartbarer Code oder auch schlechtere Performance bei unsachgemäßem Einsatz. Erreichen wir nun einen echten parallelen Betrieb oder verzetteln wir uns mit neuen Sprachen in einer Parallelen Welt?
Funktional? Egal!
Funktionale Sprachen wie Nemerle oder F# werden aus diesem Blickwinkel vielleicht interessanter. Warum? Die Probleme von Code, vor allem die von parallelem, rühren unter anderem daher, dass Code an Stelle A einen anderen an Stelle B ändert ohne über diesen Umstand zu informieren, oder darauf gefasst zu sein, dass er noch von Stelle C verwendet wird. Die funktionalen Sprachen wollen diesen Umstand beseitigen. Wie sie das anstellen wollen? Indem sie per Definition alle Variablen implizit immutable, also unveränderlich, definieren. Das ginge freilich auch mit einer Sprache wie C#, nur muss dies erst einmal getan werden.
Weil zuerst einmal von unveränderlichen Variablen ausgegangen wird, wie sie in der Mathematik Verwendung finden, wird dieser Zustand durch Tools erkennbar. Der Compiler muss keine aufwendige Prüfung durchführen. Wenn Code per Definition nicht veränderbar ist, kann auch nichts kaputt gehen. Aber wie bekommen wir dann Zustandsänderungen hin? Durch das Kopieren der Inhalte auf neue Instanzen der Variablen. Daher auch ihre eigentliche Herkunft, die wissenschaftliche Arbeit und das Lösen von Problemen mit beweisbaren Algorithmen. Das erklärte Ziel: Funktionen schreiben, die frei von Seiteneffekten sind. Wenn Funktionen frei von Seiteneffekten sind, können sie aufgeteilt und gleichzeitig ausgeführt werden da sie ja keine Abhängigkeiten besitzen. Das interessante an den Funktionalen Sprachen ist aber, dass sie bei richtiger Anwendung mathematisch beweisbar und berechenbar sind. Schaffen wir es also, komplexe Themen wie in der Mathematik kalkulierbar zu machen?
Absturzgefahr?
Soviel einmal zur Theorie. Wie sieht es aber mit der anderen Seite, der Praxis aus? Zum einen wäre da unser bestehender Code, das gleiche Problem wie wir es bereits beim Umstieg auf die .NET Plattform hatten und auch noch haben. Legacy Code will gepflegt werden. Weder verschwindet er so einfach, noch portiert er sich ganz von alleine. Das soll auch gar nicht das Ziel sein. Denn es gibt Einsatzgebiete, da eignet sich eben der imperative Ansatz einfach am Besten. Zum anderen haben wir da die Entwickler, die objektorientiert denken - und das ist gut so, sonst hätten wir heute noch viele ungelöste Probleme! Objektorientierung ist ja wie wir wissen etwas sehr gutes. Last but not least treiben die Hersteller mit Bibliotheken und Frameworks die Parallelität als Schlüssel zu mehr Leistung, und somit dem Wachstum, voran. Neuentwicklung gehen schließlich mit mehr Resourcenbedarf einher. Warum also eine neue Programmiersprache, wenn wir mit anderen Mitteln auch ans Ziel kommen. Das Erlernen einer neuen Sprache kostet Zeit und aus Sicht des Unternehmens gesehen somit viel Geld. Wie können uns hier aber die neuen Sprachen helfen? Genauso wie sie es schon früher getan haben! Interpreter (PHP, Perl, Python, Javascript) werden schon seit längerem erfolgreich eingesetzt. Die Imperativen sowieso. Sonst würden wir vermutlich heute nicht hier sitzen und diesen Text lesen. Na und die Funktionalen haben ihre Daseinsberechtigung im wissenschaftlichen Bereich. Was neu ist, ist die Kombination von allen in einer gemeinsamen Plattform. Die Sprachen werden also bunter gemischt möglich sein. Für Problem A nehmen wir C# für Problem B Python und wiederum bei C wäre eben F# schön. Wir können auch noch mehr! Nämlich die alten Quellen nehmen, die z.B. auf diesen Interpretern geschrieben wurden und diese jetzt über die Krücke CLR auch mit den anderen Sprachen benutzen.
Fest steht, dass mit der DLR endlich eine ordentliche Basis für eine Skriptumgebung unter .NET zur Verfügung steht. Damit lassen sich leicht eigene Konsolen für Anwendungen einbauen um das System dynamischer, zur Laufzeit, leichter änderbar zu machen, wie es einst schon Netscape mit JavaScript getan hat. Prototypen können damit schneller erstellt werden, für den Versuchsaufbau ein großer Vorteil, ausgelieferte Applikation damit leicht angepasst werden. Eine Funktion, für die Skriptsprachen berühmt, wenn nicht sogar berüchtigt sind. Funktionale Aspekte haben den, schon seit langem notwendig, Einzug in C# 3.0 gehalten. Doch werden diese auch richtig genutzt? Wer hat sich denn schon mal ernsthaft Gedanken über die Parallelität eines Delegaten oder eines Lambda Ausdrucks gemacht?
Alle Aspekte berücksichtigt?
Aspekte im Algemeinen als Sprachbestandteil sind wichtig! Hier haben wir ebenfalls ein Problem, dem sich Microsoft mit dem Framework oder der CLR noch nicht so richtig angenommen hat. Eine Implementierung, wie sie PostSharp bietet wäre so ein Schritt in die richtige Richtung, die uns beim parallelisieren oder aufteilen von Code zur Hand geht. Ein Beispiel dazu findet sich in der aktuellen dotnetpro 3/2009 in dem Artikel Multithreading per AOP von Gael Fraiteur. Können Sprachen wie Boo hier vielleicht eine Möglichkeit bieten eigene Syntax für Aspekte zu entwerfen? Aspekte führen bekannter Maßen zu weniger dupliziertem Code durch Trennung der Belange.
Auf zum Photofinish
Was erwartet uns dann also? Die Version 4.0 macht dem .NET-Framework dynamische Beine. Mein Tipp für .NET 5.0 ist: Die Beine werden dann auch noch so richtig funktional. Die nächste General Purpose Sprache, wie sie C# im Moment ist, muss noch einiges mehr im Portfolio bereithalten um dem versierten und professionellen Entwickler alle geeigneten Mittel mit auf den Weg zu geben. Die Techniken und Prinzipien sind schon seit Jahren bekannt und finden in anderen Sprachen großen Anklang. Sie sind reif dafür in den Mainstream einzufließen. Liegt es an Microsoft und seinen Ingenieurteams eine weitere Erfolgsgeschichte zu schreiben, auf dem Weg eine besseren Sprache zu entwerfen? Oder müssen wir Entwickler uns endlich von dem Technologiehype lösen? Brechen wir uns auf Parkour .NET die Beine oder schaffen wir es wie in der gleichnamigen Trendsportart die Hindernisse elegant mit unseren akrobatischen Fähigkeiten zu überwinden? Jeder dem Professionalität am Herzen liegt sei also einmal die Frage ans Herz gelegt: Brauche ich das wirklich alles, oder kann ich damit einfach nur schön spielen. Ich bestimmten Bereichen ist, wie gezeigt, der Einsatz durchaus sinnvoll.