Haxe (Programmiersprache)
# Haxe (Programmiersprache)

Haxe ist eine objektorientierte, JavaScript-ähnliche Programmiersprache. Die Möglichkeit, aus Haxe-Code ausführbare Programme für Adobe Flash, JavaScript, PHP, C++ und Neko VM zu erzeugen, zusammen mit leistungsfähigem Remoting (Fähigkeit, Objekte und Methodenaufrufe an andere Systemen zu senden, siehe eigener Abschnitt), machen Haxe ideal für die Programmierung von Webanwendungen, weshalb es auch als universelle weborientierte Sprache bezeichnet wird.

## Geschichte

Das französische Unternehmen Motion Twin wurde 2001 gegründet und beschäftigt sich seitdem mit der Entwicklung von Flash-basierten Webseiten und Spielen. Die Entwicklung von Haxe ist eng mit der Unternehmensgeschichte verwoben. Als Erfinder von Haxe gilt Nicolas Cannasse, Mitbegründer von Motion Twin.

### 2003 bis 2005: Tools für die Arbeit mit ActionScript

Um sich die Arbeit mit ActionScript zu erleichtern, begann Motion Twin im Dezember 2003 mit der Entwicklung der ActionScriptMetaLanguage. Darin geschriebene Programme werden durch einen eigenen Vorcompiler in gewöhnliches ActionScript umgewandelt. In diesem Schritt wird Typ- und Parameterprüfung zu Compilezeit durchgeführt, wobei auch die weiter unten erläuterte Typinferenz zum Einsatz kommt. Der resultierende ActionScript-Code wird dann mittels des Compilers von Flash in eine SWF-Datei umgewandelt, welche dann beim Nutzer mittels Flash Players angezeigt wird. Zum Vergleich: Ohne den Einsatz der ActionScriptMetaLanguage wird die Typprüfung erst zur Laufzeit möglich, was das Auffinden von Programmfehlern erschwert.

Im April 2004 wurde die ActionScriptMetaLanguage um neue Typen erweitert und nannte sich von da an MotionTypes. Wenig später erhielt der Compiler die Fähigkeit, direkt SWF-Bytecode zu erzeugen, ohne den Umweg über den Macromedia-Compiler zu gehen.

Sowohl ActionScriptMetaLanguage als auch MotionTypes werden nur innerhalb des Unternehmens genutzt. Im Gegensatz dazu wurde MTASC, der MotionTwin Actionscript Compiler im Oktober 2004 als Betaversion der Öffentlichkeit vorgestellt. Dieser Compiler ist unabhängig von MotionTypes, denn er erstellt aus gewöhnlichem ActionScript (welches inzwischen die Sprachversion 2.0 erreicht hatte) SWF-Bytecode. Zusammen mit anderer freier Software ergab sich das Programmpaket FAMES (bestehend aus Flashout, ASDT, MTASC, Eclipse und SwfMill), womit es erstmals möglich war, Flashapplikationen auch ohne die proprietäre Software von Macromedia oder Adobe zu erstellen.

Am 14. Juli 2005, nur zwei Tage nach der öffentlichen Vorstellung des Flash Player 8, unterstützte MTASC bereits diese Flash-Version.

### Ab 2005: Aufbau einer eigenen Sprache und Technologie

Zunächst wurde geplant, die (ebenfalls von Motion Twin entwickelte) Sprache Neko zukünftig in den Mittelpunkt zu stellen, und Neko mit anderen Technologien, wie z. B. ActionScript 2.0, Java und Ruby, zu kombinieren.

Als seitens Adobe ActionScript 3.0 angekündigt wurde, und die zahlreichen Nutzer von MTASC darauf warteten, dass die neuen Sprachfeatures von MTASC unterstützt würden, kündigte Motion Twin an, die Entwicklung einzustellen und stattdessen die neue Technologie haXe voranzutreiben.

Die Entwicklung begann am 22. Oktober 2005. Nach Alphaversionen im November 2005 und Betaversionen um Februar 2006 folgte am 17. Mai 2006 die Releaseversion 1.0. Die Aktuelle Version ist 4.2.5, welche am 6. März 2022 veröffentlicht wurde. Der Haxe-Compiler ist freie, offene Software unter der GNU General Public License, die mitgelieferten Bibliotheken stehen unter der BSD-Lizenz.

### Benennung und Aussprache

Der ursprüngliche Name haXe wurde gewählt, weil er dem Autor zufolge „kurz, einfach und cool“ sei und ein X enthält, was, wie er scherzhaft anmerkt, notwendig sei um eine neue Technologie erfolgreich zu machen.

Es gibt keine offizielle Aussprache des Namens haXe. International verbreitete Aussprachen sind „hex“ (welches einer französischen Aussprache nahekommen soll), „häcks“ und „aytch äx“.

## Sprache

Haxe ist eine eigenständige Programmiersprache, die sich syntaktisch an JavaScript bzw. ActionScript und Java anlehnt, jedoch auch eigene Syntaxelemente einführt.

### Syntaxübersicht

Das folgende Codebeispiel bietet einen Überblick über den typischen Aufbau einer Haxe-Quelltextdatei. Dabei zeigt es auch einige fortgeschrittene Möglichkeiten, die vom Programmierer nicht zwingend beherrscht werden müssen:

An dieser Stelle sei nochmal betont, dass dieser Code ohne Änderungen in allen drei Compiler-Zielen lauffähig ist.

### Feature-Übersicht

Die meisten der folgenden Haxe-Features sind auch aus weit verbreiteten objektorientierten Sprachen wie C++ oder Java bekannt und werden daher nicht näher erläutert:

* Strukturierung großer Projekte mittels packages
* Dokumentation mittels speziellen, Javadoc-ähnlichen Kommentaren
* Klassen mit Typparametern, wobei neuere Versionen Template-ähnliche Vorzüge bieten
* Einfachvererbung und das Implementieren von (auch mehreren) Interfaces
* Zugriffsmodifikatoren wie z. B. private und static
* Eigenschaften, deren Zuweisung über Zugriffsfunktionen (Getter und Setter) abgewickelt wird
* Konstruktoren und Destruktoren
* Main-Methode muss auch innerhalb einer Klasse untergebracht sein
* For-Each-Schleife (andere Formen der For-Schleife gibt es in Haxe nicht)
* Iteratoren (im Codebeispiel nicht gezeigt)
* Reflection (im Codebeispiel nicht gezeigt)

Folgende Features, die viele gängige Sprachen bieten, fehlen jedoch in Haxe:

* Methodenüberladung
* Mehrfachvererbung
* Abstrakte Klassen

### Typinferenz

Programmiersprachen sind für gewöhnlich statisch oder dynamisch typisiert. Bei statischer Typisierung ist jeder Variable, jedem Attribut und jedem Parameter eindeutig ein Typ zuzuordnen, der zur Laufzeit konstant bleibt.

In einer dynamisch typisierten Sprache haben Variablen, Attribute und Parameter keinen klar definierten Typ:

Haxe verbindet beide Ansätze. Zum einen ist es dem Programmierer freigestellt, ob der Typ einer Variablen angegeben wird, oder nicht. Zum anderen schlussfolgert (Inferenz bedeutet Schlussfolgerung) der Compiler selbständig den Typ jeder Variable, die nicht vom Programmierer festgelegt wurde, und behandelt sie, als wäre sie statisch typisiert. Als dritte Alternative kann der Programmierer sie explizit als Dynamic deklarieren und somit die Typinferenz aushebeln:

Die Sprachen, für die Haxe einen Ersatz darstellen kann (Javascript, ActionScript, PHP etc.) sind in der Regel dynamisch typisiert. Der Vorteil der Typinferenz sei nochmals an folgendem Beispiel gezeigt:

Das Array retval ist vom Programmierer nicht typisiert. Jedoch kann der Compiler aus dem Methodenkopf erkennen, dass das Array vom Typ Int sein muss, um später als Rückgabewert zu dienen. Das Einfügen des Wertes 5.001 widerspricht dem, somit wird der Compiler einen Fehler melden. Ohne Typinferenz würde dieser Fehler erst zu Laufzeit auffallen, und auch erst bei Ausführung der markierten Zeile. Aufgrund der if-Bedingung würde dies erst nach ca. 1000 Testläufen auftreten, d. h. eventuell erst, wenn die Software zum Kunden ausgeliefert wurde.

### Konditionales Kompilieren

Ein Großteil des Haxe-Codes ist auf allen Zielplattformen lauffähig (siehe Abschnitt Zielplattformen). Dennoch kommt man oft nicht um plattformspezifische Anpassungen herum. Diese können wie folgt eingebunden werden:

### Aufzählungstypen

Aufzählungstypen sind eine Schlüsselfunktion der Sprache. Sie können selbst Parameter haben und rekursiv sein, was ihnen erlaubt, wie Klassen behandelt zu werden. Enums in Haxe sind nicht einfach nur indizierte „magic-numbers“ wie in den meisten Sprachen, sondern sind abstrakter: Sie haben keinen eigenen Wert, aber können instantiiert werden, wie das folgende Beispiel zeigt:

### Weitere Details

Funktionsparameter können in Haxe sehr genau definiert werden:

## Zielplattformen

In Haxe geschriebener Code wird kompiliert (im Gegensatz zu anderen Sprachen, welche interpretiert werden). Dabei kann man zwischen folgenden Zielen wählen:

* Flash, genauer:
   * SWF-Bytecode für AVM 1 (entspricht Flash 6, 7, 8)
   * SWF-Bytecode für AVM 2 (entspricht Flash 9)
   * ActionScript 3.0 Sourcecode
* JavaScript
* Neko VM
* C++ (ab Version 2.04)
* PHP (ab Version 2.0)
* Java Bytecode
* C# Bytecode (experimentell)

Das ansonsten eher unbekannte Neko verdient hierbei besondere Beachtung: Es kann einerseits serverseitig eingesetzt werden (als Standalone-Server oder als Apache-Modul modneko). Andererseits kann es auch direkt beim Client eingesetzt werden. Dazu muss dieser die Neko-VM auf seinem Rechner installieren. Mittels Screenweaver HX ist es möglich, Desktopanwendungen mittels Haxe umzusetzen, bei denen die Logik in Neko umgesetzt ist, das Userinterface jedoch mittels Flash.

Ab der Version 2.0 wird auch PHP als serverseitige Sprache unterstützt, welches auf Webservern meist vorinstalliert ist, im Gegensatz zur eher unbekannten Neko VM.

In Haxe geschriebene Klassen kann man nach der Kompilierung als SWF in Actionscript-Code verwenden, umgekehrt können kompilierte Actionscript-Klassen von Haxe-Code verwendet werden, man kann sogar davon ableiten.

### Bibliotheken und APIs

Der Sprachkern von Haxe und eine Reihe von mitgelieferten Bibliotheken sind für alle Zielplattformen verfügbar. Dazu gehören zwei verschiedene XML-APIs (beide sind überall verfügbar), reguläre Ausdrücke, Exceptions, Remoting, Reflection, Math (trigonometrische Funktionen, Pseudozufallszahlen etc.) und der Umgang mit Daten und Zeiten. Solange eine Klasse nur von diesen APIs Gebrauch macht, kann sie ohne jegliche Anpassungen für alle Ziele kompiliert werden. Es ist für den Programmierer irrelevant, ob es sich dabei um Wrapper handelt (welche eine native Bibliothek kapseln), oder diese komplett in Haxe implementiert sind. Sprachmerkmale von Haxe, die in der Zielsprache nicht vorhanden sind (z. B. Interfaces, Generik etc.) bereiten hierbei keine Probleme, denn sie werden vom Compiler in äquivalenten Code umgesetzt.

Darüber hinaus bietet Haxe vollen Zugriff auf die plattformspezifischen APIs. Bei Flash betrifft das z. B. MovieClips und Grafikfilter, bei Javascript die Interaktion mit dem Browserfenster, und bei Neko zugriff auf Systemressourcen wie etwa lokale Dateien.

### Grafische Benutzerschnittstellen

Haxe ermöglicht zwar, Großteile der grafischen Benutzerschnittstelle damit umzusetzen, jedoch stößt die Portabilität hier eindeutig an ihre Grenzen. Es ist ohne zusätzliche Softwarepakete nicht möglich, eine einzige GUI zu schreiben, welche in Flash, HTML/Javascript und als Desktopanwendung zugleich lauffähig ist. Dennoch ist es möglich, zwei bzw. drei getrennte GUIs zu schreiben, die denselben Anwendungskern verwenden (siehe Model View Controller).

Derzeit werden Frameworks entwickelt, um die GUI einmalig zu beschreiben, sodass sie auf den verschiedenen Plattformen gleichwertig angezeigt wird und die gleiche Anwendung darstellt. So stellt jeash die aus Flash bekannten Klassen auch in JavaScript bereit (mittels des Canvas-Elements aus HTML5). Für die Entwicklung in C++ leistet neash das gleiche. Auf diese Weise lassen sich Flash-ähnliche Inhalte auch auf Mobilplattformen wie Android und iPhone bereitstellen.

## Rich Internet Applications – Vergleich zwischen Haxe und anderen Lösungen

Heutige Rich Internet Applications unterscheiden sich von klassischen Webseiten dadurch, dass sich zunehmend Anwendungslogik vom Server auf den Client verlagert. Dies ermöglicht schnellere Reaktionen auf Benutzereingaben, weniger Traffic und ein Desktop-ähnliches Look and Feel. Um solche RIAs zu entwerfen waren bis vor kurzem eine Vielzahl von Programmiersprachen nötig. Haxe und auch andere aktuelle Ansätze (siehe Ende des Abschnitts) ermöglichen die Arbeit mit einer einzigen Sprache.

### Umsetzung mit mehreren Sprachen

Zum Erstellen von RIAs konkurrieren seit längerem zwei Technologien: Ajax und Flash. Zwar sind Java-Applets die älteste und ausgereifteste Technologie in diesem Bereich, konnten jedoch beim durchschnittlichen Nutzer nie die Bedeutung von Javascript und Flash erreichen. Neue Technologien wie JavaFX, das Flash-basierte Flex und Microsoft Silverlight drängen ebenfalls in diesen Bereich, indem sie neue Sprachen (JavaFX Script, MXML und XAML) einführen, die meist mit den bereits vorhandenen kombiniert werden.

Allen Konzepten gemeinsam ist, dass die Webanwendung verteilt abläuft: Die Benutzeroberfläche und zeitkritische Teile der Logik laufen beim Client (innerhalb des Webbrowsers), die Datenhaltung und alle sicherheitsrelevante Logik befindet sich auf dem Server. Die Kommunikation findet asynchron (d. h. vom Anwender unbemerkt im Hintergrund) mittels HTTP statt. Um diese Webanwendungen auch offline und ohne Browser verfügbar zu machen, muss der Nutzer auf seinem Rechner auch die Teile ablaufen lassen, die ursprünglich auf den Server ausgelagert wurden. Dies wird teilweise durch Adobe Integrated Runtime (AIR) und Gears ermöglicht.

Quasi alle oben genannten Techniken erfordern vom Entwickler, verschiedene Sprachen zu beherrschen, im Extremfall sind dies HTML, CSS, XML, JavaScript, ActionScript und eine serverseitige Sprache wie z. B. PHP, Ruby, Perl oder Java. Zudem müssen die Einzelteile auch sprachübergreifend zusammenarbeiten, wofür meist ein XML- oder ein textbasiertes Interface zwischen diesen geschaffen werden muss. Die Arbeit mit diesen Sprachen wird dadurch erschwert, dass sie nicht nur eine andere Syntax, sondern oft ein komplett anderes Typsystem besitzen. So ist die Objektorientierung in Javascript grundverschieden von z. B. der in Java.

### Umsetzung mit Haxe

Bei der Entwicklung mit Haxe können Server-, Client- und gegebenenfalls Desktop-Komponenten in derselben Sprache verfasst werden. Zudem ermöglicht es das Haxe-Remoting, Objekte und Methodenaufrufe über Sprach- und Rechnergrenzen hinaus zu versenden. Somit muss der Entwickler

* nur noch eine Programmiersprache beherrschen (Auszeichnungssprachen wie HTML und CSS können weiterhin nötig sein)
* sich nicht frühzeitig entscheiden, ob ein Programmteil client- oder serverseitig ablaufen soll
* sich nicht frühzeitig entscheiden, ob er dem Benutzer eine Flash- oder Ajax-Oberfläche bieten möchte
* keine textuellen Interfaces zwischen den Anwendungsebenen entwerfen und implementieren

Haxe bietet sich also vor allem bei mehrschichtigen Webanwendungen an. Aufgrund von Sprachfeatures, die anderen Sprachen oft fehlen, kann Haxe auch schon bei einfachen, einschichtigen Anwendungen die Entwicklung erleichtern.

### Andere Ansätze mit einer einzigen Sprache

Sowohl Rich Ajax Platform als auch Google Web Toolkit ermöglichen dem Entwickler, RIAs zu entwickeln und dabei sowohl die Client- als auch die Serverseite in Java zu programmieren. Beide generieren daraus ein Servlet sowie clientseitigen Code in Javascript. Anders als Haxe bieten beide eigene Widgets an, aus denen automatisch HTML-Seiten erzeugt werden. Im Gegensatz dazu erfordert Haxe vom Entwickler, selbst HTML zu generieren, es sei denn, er verzichtet komplett auf den Einsatz von HTML. Flash wird von diesen beiden Lösungen nicht unterstützt, allerdings kann Rich Ajax Platform eigenständige Desktopanwendungen auf SWT-Basis erzeugen.

OpenLaszlo verwendet zwar nicht nur eine einzige Sprache, denn in den deklarativen XML-Dialekt LZX wird ECMAScript eingebettet. Ähnlich wie Haxe kann OpenLaszlo daraus jedoch auch eine Flash- als auch eine DHTML-Oberfläche erzeugen. Insofern ist es Haxe überlegen, da Haxe seinerseits kein Userinterface generieren kann (siehe Abschnitt Grafische Benutzerschnittstellen weiter oben).

## Remoting

Haxe ermöglicht es, zwischen den unterstützten Plattformen quasi beliebig Objekte und Methodenaufrufe zu versenden. Dabei stehen in jedem Fall synchrone und asynchrone Verbindungen zur Verfügung. Das Verfahren ähnelt Remote Procedure Call.

So können Flash-Objekte und Javascripts innerhalb einer Seite untereinander kommunizieren, und beide können direkt auf einen Neko-Server zugreifen. Auf gleiche Weise können Server bzw. Neko-Desktopanwendungen auch untereinander kommunizieren. Darüber hinaus können mit haXe geschriebene Flashprogramme auf einen Flash Media Server (auch AMFPHP) zugreifen.

Folgender Quellcode könnte in Flash, Javascript oder einem zweiten Neko-Server benutzt werden, um auf einem Neko-Server die Methode meineMethode aufzurufen. Der Rückgabewert bzw. eine dort geworfene Exception wird an eine der beiden lokalen Callback-Methoden weitergeleitet:

Über die bei Ajax üblichen HTTP-Anfragen an den Server werden damit andere Einsatzmöglichkeiten denkbar. Ein mögliches Anwendungsbeispiel: Eine RIA mit HTML-Oberfläche und Anwendungslogik in Javascript enthält eine aufwändige Berechnung. Falls auf dem Nutzerrechner Flash verfügbar ist, wird sie an ein 1×1-Pixel großes Flashobjekt delegiert (unter der Annahme, dass Flash-Bytecode deutlich schneller ausgeführt wird als Javascript). Ist kein Flash verfügbar, so wird die Berechnung auf dem Server ausgeführt. Falls weder der Server noch Flash verfügbar sind, läuft die Berechnung lokal per Javascript. Die Berechnung selbst muss dabei nur ein einziges Mal in Haxe implementiert werden.

## Compiler-Implementierung und Performanz

Der Haxe-Compiler ist in Objective CAML implementiert. Da Haxe-generierter Code in virtuellen Maschinen läuft, ist jedoch keine weitere Kenntnis dieser Sprache nötig, um mit Haxe Anwendungen zu entwickeln. Dies bedeutet auch, dass die Performanz je nach Zielplattform variiert, da jede Plattform angepasst werden muss, damit die verfügbaren Ressourcen bestmöglich ausgenutzt werden können.

Ein Benchmark zeigt, dass Haxe Flash-9-Bytecode (AVM2) mit besserer Performanz kompiliert als der äquivalente AS3-Code auf Adobes Compiler. Seit diesem Leistungstest wurde der Compiler noch weiter verbessert, u. a. durch das Hinzufügen von Inline-Funktionen.

Um das Übersetzen mehrerer Klassen für verschiedene Kompilierziele zu vereinfachen, werden hxml-Dateien verwendet. Dies sind einfache Textdateien mit Anweisungen für den Compiler. Per Doppelklick auf diese kann somit das gesamte Projekt kompiliert werden.

Da der Compiler eine Kommandozeilenanwendung ist, lässt er sich auch in vorhandene Entwicklungsumgebungen einbinden. FlashDevelop bringt von Haus aus Unterstützung für Haxe mit sich.

