Fandom

Mini-Wikia

Fantom-DE/Besonderheiten

< Fantom-DE

1.771Seiten in
diesem Wiki
Seite hinzufügen
Diskussion0 Teilen

Störung durch Adblocker erkannt!


Wikia ist eine gebührenfreie Seite, die sich durch Werbung finanziert. Benutzer, die Adblocker einsetzen, haben eine modifizierte Ansicht der Seite.

Wikia ist nicht verfügbar, wenn du weitere Modifikationen in dem Adblocker-Programm gemacht hast. Wenn du sie entfernst, dann wird die Seite ohne Probleme geladen.

Brauchen wir wirklich noch eine weitere Programmiersprache? Die Schöpfer von Fantom waren offenbar dieser Meinung, denn andernfalls hätten sie diese Sprache nicht erfunden. Fantom ist aus langjährigen Erfahrungen mit der Sprache Java und deren Defiziten heraus entstanden, von denen viele sicher auch auf C# zutreffen. Diese Seite gibt einen Überblick über die wichtigsten Eigenschaften von Fantom als Sprache und Entwicklungsframework.

Portabilität

Einer der Hauptgründe für die Entwicklung von Fantom besteht in dem Bedarf für Programme, die problemlos sowohl auf der Java-VM als auch der .NET CLR laufen können. Tatsächlich sind viele Organisationen entweder auf die eine oder die andere Plattform festgelegt. Sogar dynamische Sprachen wie Python und Ruby werden zunehmend auf eine dieser virtuellen Maschinen betrieben. Unabhängig davon, ob Software für den eigenen Bedarf oder für den Verkauf an andere Firmen geschrieben wird, gibt es eine Tendenz, sich entweder dem einen oder dem anderen Lager zuzuordnen.

Fantom ist von vorne herein so aufgebaut, dass sie zwischen diesen VMs portabel ist. Die Quellprogramme werden in F-Code kompiliert, dies ist eine Bytecode-Repräsentation, die sich leicht in Java-Bytecode oder IL übersetzten lässt. Diese Übersetzung findet typischerweise zur Laufzeit statt, so dass Sie Fantom-Module als eine einheitliche Datei herausgeben und auf beiden VMs laufen lassen können.

Aber eine Sprache zu bauen, die sowohl der JVM als auch auf .NET läuft, ist erst der Anfang. Tatsächlich gibt es bereits viele Lösungen für dieses Problem. Schwierig wird es erst, wenn man auch portable APIs haben möchte. Fantom bietet eine Reihe von APIs, die eine Abstraktion der Java- und .NET-APIs darstellen. Dies ist einer der Hauptvorteile von Fantom, denn es ermöglicht die Entwicklung eines Satzes von System-APIs, die im Vergleich zu ihren Java- und .NET-Gegenstücken elegant und einfach zu verwenden sind.

Alledings ist Portabilität mehr als nur Java oder .NET. Man kann Fantom auch nach JavaScript kompilieren, um es im Browser laufen zu lassen. Dabei ist auch die Unterstützung zahlreicher Standardbibliotheken eingeschlossen.

Da Fantom von Grund auf für den portablen Einsatz entworfen wurde, ist die Aufnahme neuer Zielplattformen relativ einfach. Zukünftige Zielplattformen könnten Objective-C für das iPhone, die LLVM oder Parrot sein.

Elegante APIs

Die Java- und .NET-APIs haben sich in Laufen der Jahre zu einem ziemlichen Wust entwickelt. Manche von ihnen sind einfach nur schlecht. Eines der Vorzeigebeispiele für eine besonders misslungene API gilt die Calendar-Klasse in Java, bei der man sonderbare C-ähnliche Konstanten für den Zugriff verwenden muss und bei der Monate Null- und Wochentage Eins-basiert sind!

Manches in den Bibliotheken ist einfach nur überflüssiges Zeug, das sich im Laufe der Zeit angesammelt hat. Vieles resultiert aber auch aus einer generellen Philosophie, die man in den API-Designs sowohl von Java als auch von .NET findet. Beide Plattformen haben eine Vorliebe für APIs, die aus einer Vielzahl kleiner, übermäßig abstrahierter und für sich wenig leistungsfähiger Klassen bestehen. Dagegen folgt Fantom einer ganz anderen Philosophie: Es gibt nur wenige Klassen mit jeweils großem Funktionsumfang. Ein gutes Beispiel dafür ist das Package java.io, bestehend aus über 60 Klassen und Interfaces. Um etwas Sinnvolles damit anfangen zu können, braucht man drei bis vier Klassen, und wenn man vergisst, gepufferte Streams zu verwenden, geht die Performance zum Teufel. Selbst wenn man alle diese Klassen beisammen hat, bereiten elementare Dinge wie das Einlesen einer Datei in Textzeilen immer noch viel Arbeit. In Fantom ist der Großteil der java.io-Funktionalität auf vier Klassen verteilt: sys::File, sys::Buf, sys::InStream und sys::OutStream. Dabei sind die Stream-Klassen standardmäßig gepuffert, unterstützen sowohl Binär- als auch Textdaten und sind bequem zu benutzen.

Strenge oder dynamische Typisierung

In der Software-Branche hat sich ein Schisma zwischen den Anhängern der strengen Typisierung und der dynamischen Typisierung entwickelt. Fantom findet sich irgendwo zwischen diesen Extremen und bietet einen moderaten Zugriff auf sein Typsystem.

Fantom ist insofern streng typisiert, als es die Kennzeichnung von Feld- und Methodensignaturen mit Typen erfordert. Das ist wichtig, weil es beim Programmieren um die Konstruktion wohldefinierter Kontrakte zwischen Software-Komponenten geht. Typsysteme sind nicht perfekt, aber sie ermöglichen es uns ganz gut, diese Kontrakte zu definieren und zu dokumentieren. Wenn ich eine Methode schreibe, die einen Str erwartet und ein Int zurückliefert, dann sollte dies im Code auch deutlich werden.

Aber jenseits der Typkennzeichnung von Feld- und Methodensignaturen nimmt Fantom eher eine Laissez-Faire-Attidüde hinsichtlich der Typdeklarationen an. Häufig werden die Typen von lokalen Variablen und Kollektionsliteralen durch per Typinferenz aus dem Kontext erschlossen.

Manchmal braucht man aber auch eine dynamische Typisierung. Eine der zentralen Eigenschaften von Fantom ist die Möglichkeit, eine Methode streng oder dynamisch typisiert aufzurufen. Wenn man eine Methode mit dem Punkt-Operator aufruft, wird der Aufruf vom Compiler typgeprüft und in effizienten Opcode übersetzt. Man kann aber auch mit dem Pfeil-Operator (->) eine Methode dynamisch aufrufen. Dieser Operator lässt die Typprüfung aus erlaubt dadurch Duck-Typing. Letztlich führt er zu einem Aufruf der Methode Obj.trap, die, wenn man sie überschreibt, alle möglichen Raffinessen ermöglicht.

Generische Typen

Interessanterweise werden die Sprachen Java und C# immer strenger typisiert, während Fantom versucht, die Typisierung eher zu lockern. Dieser Trend wird durch die generischen Typen illustriert, die sowohl in Java als auch in C# erst vor nicht allzu langer Zeit eingebaut wurden. Ein voll parametrisiertes Typsystem bringt eine Menge zusätzlicher Komplexität mit zweifelhaftem Nutzen mit sich.

In Fantom spielen generische Typen eher eine begrenzte Rolle. Benutzerdefinierte Generics werden zwar nicht unterstützt, aber es gibt drei eingebaute Klassen (List, Map und Func), die mit Hilfe einer speziellen Syntax parametrisiert werden können. Beispielsweise kann man in Fantom eine Liste von Ganzzahlen als Int[] deklarieren, indem man die aus Java und C# vertraute Syntax der Array-Typen anwendet. Auf diese Weise können Generics benutzt werden, wo sie Sinn geben, ohne dass das Typsystem als Ganzes zu verkompliziert wird.

Mixins

Häufig stellt das Programmieren ein Modellierungsproblem dar: Herausbekommen, wie man ein Domainmodell in Code abbildet. In der objektorientierten Programmierung heißt dies typischerweise Modellieren durch Klassen und Interfaces. Dabei verwenden Java und C# einen ähnlichen Ansatz: Klassen erlauben Einfachvererbung sowohl für den Typ als auch für die Implementierung. Interfaces erlauben Mehrfachvererbung für den Typ, aber keine Vererbung der Implementierung.

Wer jemals mit Java oder C# gearbeitet hat, weiß, dass einen die Entscheidung zwischen einer Klasse oder einem Interface geradezu heimsuchen kann. Sobald Sie sich für eine Klasse entscheiden, haben Sie Ihre einzige Möglichkeit, Implementierung zu vererben, verbrannt. Wenn Sie ein kompliziertes Domainmodell haben, wird die Verwendung von Interfaces eine unvermeidliche Last, die aber häufig zu viel Arbeit führt, wenn Sie gemeinsam genutzten Implementierungscode haben. Außerdem gefährden Interfaces die Zukunftssicherheit Ihrer Programme, denn Sie können keine Methoden hinzufügen, ohne dass sämtlicher implementierender Code angepasst werden muss.

Es gibt viele gute Gründe, warum man sich bei Java und C# für die Verwendung des Klassen-Interface-Modells entschieden hat. Mehrfachvererbung eröffnet viele Möglichkeiten, bringt aber erhöhte Komplexität und einige böse Fallen mit sich. Auch hier schlägt Fantom den Mittelweg ein und verwendet sogenannte Mixins. Dies sind im Prinzip Java- bzw. C#-Interfaces, die auch Methodenimplementierungen beinhalten können. Um einige der Fallstricke der echten Mehrfachvererbung zu vermeiden, gibt es bei Mixins einige Restriktionen, beispielsweise in Bezug auf Felder, die einen Zustand halten. Im Fantom-Werkzeugkasten bilden Mixins nette Möglichkeiten für das Design Ihrer objektorientierten Modelle

Modularität

Dass Software modular entworfen werden sollte, lernen Sie im ersten Semester des Informatik-Studiums. Modularität ist eine fundamentale Eigenschaft guter Programme. Sie ermöglicht es, Anwendungen in wieder verwendbare Stücke aufzuteilen, die man leicht versionieren und versenden kann und die sich mit über klare Abhängigkeiten mit anderen Modulen kombinieren lassen.

Java hat für das Modulmanagement nicht mehr zu bieten als die JAR-Datei. Mit anderen Worten: Java verfügt nicht wirklich über ein Modulmanagement. es gibt einen neuen JSR, der dieses Problem möglicherweise löst, aber die letzte Dekade lang mussten wir mit der Klassenpfadhölle leben. Außerdem leidet Java an einigen fehlgeleiteten Marketing-Entscheidungen, die zu einer monolithischen J2SE von rund 44 MB geführt hat. Wenn man an die Brillanz denkt, die in vielen Teilen der ursprünglichen Java-Technologie steckt, ist es schwer zu verstehen, warum so etwas Fundamentales wie Modularität schlichtweg fehlt.

Beim Entwurf von .NET ist dagegen Modularität ziemlich ernst genommen worden, und so gibt es auf der höheren Ebene ein großartiges Konzept für Versionierung, GAC usw. Wenn man allerdings die Details betrachtet, lässt auch .NET einiges zu wünschen übrig. Während man bei Java mit ZIP eine einfache und flexible Möglichkeit zum Zusammenpacken von Dateien gewählt hat, verwendet .NET undurchsichtige DLLs mit allem möglichen Windows-spezifischen Zeug, durch die .NET-Module schwer handhabbar werden. Und dass man eine gesonderte, undokumentierte Debug-PDB-Datei benötigt, um überhaupt brauchbare Stacktraces zu bekommen, ist schlichtweg unsinnig.


In Fantom ist alles um modulare Einheiten herum entworfen, die sich Pods nennen. Pods bilden die Basis der Versionierung und des Deployments. Sie werden mittels klarer Abhängigkeiten miteinander kombiniert. Und wie bei Java handelt es sich um einfache ZIP-Dateien, die man sich auf einfache Weise ansehen kann.

Namensräume und Deployment

In Java und .NET gibt es mehr oder weniger unterschiedliche Konzepte für Namensräume und Deployment. Beispielweise verwendet Java Packages, um Code in Namensräumen, und JAR-Dateien, um Code für das Deployment zu organisieren. Das Problem besteht darin, dass es keinerlei Zusammenhang zwischen diesen beiden Konzepten gibt. Auf diese Weise wird die Klassenpfadhölle noch verschärft: Wenn Ihnen eine Klasse fehlt, erhalten Sie aus dem Klassennamen keinerlei Hinweis darauf, in welcher JAR-Datei die Klasse sich befinden könnte.

Natürlich bringt diese Trennung von Typ-Namensräument und Deployment-Namensräumen einige Flexibilität mit sich, aber auch unnötige Komplexität. Der Ansatz von Fantom ist hier ganz einfach: Namensräume werden in einer festen Hierarchie aus drei Ebenen verwaltet: pod::type.slot. Die oberste Ebene des Namensraums ist immer der Name des Pod, der gleichfalls die Einheit des Deployments und der Versionierung darstellt. Diese Konsistenz ist wichtig beim Bau umfangreicher Systeme aus Pods und deren Typen. Wenn Sie beispielsweise einen serialisierten Typ namens acme::Foo erhalten, können Sie sofort sehen, welchen Pod Sie benötigen.

Objektorientierung

Einer der größten Schwächen im Design von Java sind die primitiven Typen. Sie sind keine richtigen Objekte und stellen damit eine Anomalie dar, die zu allen möglichen hässlichen Sonderfällen führt. Andererseits sind die primitiven Typen wichtig, um – insbesondere in numerischen Programmen – eine C-ähnliche Performance zu erreichen. Inzwischen gibt es in Java zwar ein Pflaster in Form des Autoboxing, aber trotzdem ist das Typsystem uneinheitlich.

.NET löst das Problem ziemlich elegant mit Hilfe seiner Value-Typen. Dabei handelt es sich um spezielle Typen mit der Performance der primitiven Typen, die aber trotzdem sauber von System.Object abgeleitet sind.

Fantom folgt dem .NET-Modell der Value-Typen. Die drei speziellen Typen Bool, Int und Float sind Value-Typen, die unter Java als primitive Typen und unter .NET als Value-Typen implementiert werden. Diese Typen haben dieselbe Performance-Charakteristik wie die Typen boolean, long und double in Java oder C#. Aber anders als in Java sind sie sauber von Obj abgeleitet und dadurch Bestandteil einer einheitlichen Klassenhierarchie. Boxing und Unboxing wird vom Compiler bei Bedarf automatisch implementiert.

Funktionale Programmierung

Java und .NET haben ursprünglich kaum Unterstützung für funktionale Programmierung geboten. Immerhin bietet .NET Delegates, aber in Java muss man anstelle von Funktionen auf Interfaces und Closure-ähnliche Möglichkeiten durch innere Klassen zurückgreifen. Dadurch hinterlassen sie eine riesige Altlast an APIs und Code, die ohne Rücksicht auf die Möglichkeiten der funktionalen Programmierung entworfen wurden.

Fantom wurde von Anfang an so entworfen, dass es Funktionen als Erste-Klasse-Objekte unterstützt. Closures stellen eine Schlüsseleigenschaft der Sprache dar, und alle APIs wurden so geschrieben, dass sie Funktionen und Closures verwenden, wo immer dies sinnvoll ist.

Deklarative Programmierung

Oft genug müssen wir in unseren Programmen Datenstrukturen deklarieren. Zu den üblichen Beispielen gehört die Deklaration einer Liste oder Map. In Java und C# verursachen diese einfachen Aufgaben viel Rauschen, das deklaratives Programmieren hässlich und geschwätzig macht. Aus diesem Grund werden deklarative Teile aus Java- und C#-Anwendungen häufig in XML-Dateien abgeschoben.

Bei Fantom ist das deklarative Programmieren direkt in die Sprache eingebaut. Es werden literale Ausdrücke für Listen, Maps, Wertebereiche, URIs und Zeiten unterstützt. Außerdem enthält Fantom eine textuelle Syntax für die Serialisierung, die eine saubere Untermenge der Programmiersprache bildet und es ermöglicht, eine serialisierte Datei als Ausdruck direkt in den Quellcode zu kopieren.

Nebenläufigkeit

Die meisten Mainstream-Sprachen verwenden heutzutage ein Modell mit gemeinsam verwendetem Zustand: Alle Threads teilen denselben Speicherraum, und die Programmierer müssen zur Vermeidung von Race-Conditions sorgfältig Sperren setzen. Werden die Sperren nicht korrekt verwendet, kann es zu Deadlocks kommen. Das ist ein Ansatz auf ziemlich niedrigem Niveau, um mit Nebenläufigkeit umzugehen, und erschwert den Bau zusammensetzbarer Software-Komponenten.

Fantom löst das Problem der Nebenläufigkeit mit folgenden Techniken:

  • Immutablität ist direkt in die Sprache eingebaut (Thread-sichere Klassen)
  • Statische Felder müssen immutabel sein (kein gemeinsamer veränderbarer Zustand)
  • Aktorenmodell für die Übergabe von Meldungen (Nebenläufigkeit im Stil von Erlang)

Kleinigkeiten

Das Schöne an einer neuen Sprache ist, dass man hemmungslos all die kleinen Dinge verändern kann, die einen ärgern. Darum enthält Fantom noch einiges mehr, was wir an Java vermissen:

  • Default-Parameter: Methoden können Parameter mit Vorgabewerten haben. Nie wieder überflüssigen Code für Bequemlichkeitsmethoden mit vordefinierten Parameterwerten schreiben.
  • Typinferenz: Lokale Variablen werden durch Rückschluss typisiert. Dies vermeidet das ganze Rauschen, das typische Java-Programme so undurchsichtig macht.
  • Feld-Akzessoren: Zugriffsmethoden für Felder („Getter“ und „Setter“) werden implizit definiert. Auch dies ist ein Gebiet, wo bei Java Code- und Funktionsumfang weit auseinander klaffen.
  • Nullfähige Typen: Ob null ein zulässiger Wert für eine Variable, einen Parameter oder einen Rückgabewert ist, kann man durch Deklaration festlegen und muss sich nicht auf die Dokumentation verlassen.
  • Checked Exceptions: Geprüfte Exceptions sind ein Übel in der Syntax, da sie Skalierbarkeit und Versionierbarkeit stören und die Konstruktion zusammensetzbarer Systeme behindern. Aus all diesen Gründen hat Anders Heilsberg sie nicht in C# aufgenommen und aus all denselben Gründen fehlen sie auch in Fantom.
  • Numerische Genauigkeit: Fantom unterstützt keine Ganz- und Fließkommazahlen im 32-, 16- oder 8-Bit-Format. Es gibt nur 64-Bit Int und 64-Bit Float. Dies vermeidet eine Menge Komplexität im Zusammenhang mit Präzisionsproblemen, z.B. bei Dateilängen, Unicode-Zeichen oder sehr langen Listen. Wenn auch die Java- und C#-Implementierungen unter der Haube mit 16-Bit-Zeichen und 32-Bit-Integers arbeiten, sind die Fantom-APIs an sich zukunftssicher.

[[Kategorie:|Kategorie:]]

Auch bei Fandom

Zufälliges Wiki