- Aleph (Programmiersprache)
-
Aleph ist eine objektorientierte, funktionale Programmiersprache. Sie stellt die herkömmliche Programmierung auf eine breitere Basis. So ist interaktive Entwicklung und Kompilierung vereint. Die Arbeit mit Aleph ist am Problem orientiert und erlaubt so den gemischten Einsatz grundlegender Techniken von LISP, Forth und Java.
Auf Initiative des Vereins e-Vocation e. V. wurde Aleph 2005 begonnen. Mittlerweile haben sich „Dialekte“ entwickelt, von denen Pagkalos (griech.: das Schöne) am weitesten fortgeschritten ist.
Inhaltsverzeichnis
Entstehungsgeschichte
Aleph ist die Weiterführung eines evolutionären Prozesses. Dessen Grundlagen wurden 1969 von Charles Moore mit der Sprache Forth gelegt. Zum ersten Mal wurde eine Programmiersprache für eine rein virtuelle Maschine definiert. Alle Daten werden über einen Stack bearbeitet. Dadurch nähert sich eine Forth-Maschine dem Ideal Turing-Maschine sehr viel mehr als herkömmliche Maschinen.
Durch die rasant fortschreitende Entwicklung neuer Prozessoren und des verfügbaren Speicherplatzes wurde der Einsatz von Parser- und Compilergenerator möglich. Sprachen wie Pascal, C, C++ usw. konnten nun einfach für den vorhandenen Prozessor erzeugt werden. Diese herkömmlichen Sprachen unterstützen die gängige Schreibweise bei einfachen Berechnungen. Forth galt nun als zu unleserlich und geriet ins Hintertreffen.
Beschleunigt durch sinkende Preise für Hardware und die immer höher werdenden Anforderungen an Software, wurden herkömmliche Sprachen immer komplizierter. Mehr und mehr syntaktische Elemente wurden erdacht. Die Einführung der komplexen Datentypen verlangte strenge Prüfungen. Die Entwicklung gipfelte in der objektorientierten Programmierung. Wie sich Aleph und Pagkalos aus den verzweigten Verwandtschaften der Programmiersprachen entwickelt haben, zeigt folgende Übersicht:
Java und Forth benutzen indirekt die physische Maschine. Entweder über C/C++ oder direkt über den Assembler. Es sind stets physikalische Adressen zu beachten. Aleph hat eine virtuelle Maschine aus reinem Java-Code. Deshalb sind physikalische Gegebenheiten zwar vorhanden, aber nicht nutzbar. Nicht einmal indirekt kann Aleph eine bestimmte Adresse ansprechen; stets ist Java davor und verbietet den physischen Kontakt.
Namensgebung
Der Name Aleph leitet sich aus den Fähigkeiten der Sprache ab. Aleph macht jedes erreichbare Java-Element sofort und ohne Kompilierung verfügbar. Weil Java auch als die Sprache des Internets bezeichnet wird, gibt es eine nicht zu überblickende Menge von Java-Programmen im Netz. So umfangreiche Mengen werden oft als unendlich bezeichnet. So falsch diese Ansicht in mathematischer Hinsicht ist, so zutreffend ist sie für den Namen. Mit ℵ0 „Aleph-0“ bezeichnete Georg Cantor die erste Stufe der Hierarchie von Unendlichkeiten. Es ist die Kardinalzahl oder Mächtigkeit aller unendlichen aber abzählbaren Mengen. Georg Cantor ist der Vater der modernen Mengenlehre. Zu seinen Ehren und weil Aleph ebenfalls mit großen Mengen arbeiten kann trägt sie diesen Namen.
Das Sprachkonzept
Aleph ist sowohl Compiler- als auch Interpretersprache. Sie ist sogar beides gleichzeitig. Während interpretiert wird, kann compiliert werden und andersherum. Außer Aleph hat nur Forth diese Fähigkeit.
Das Sprachkonzept von Aleph ist näher an dem einer natürlichen Sprache als einer Programmiersprache. Damit könnte Aleph als nicht kontextfrei angesehen werden. Tatsächlich ist Aleph kontextfrei wenn es verlangt wird. Auch diese Fähigkeit teilt Aleph mit Forth.
Diese hoch geschätzte Erweiterung ergibt sich aus der nicht vorhandenen Grammatik. Es gibt nicht einmal eine Syntax im eigentlichen Sinne. Die Regeln werden durch die Programmierung selbst festgelegt. Das macht Aleph zu einer wirklich objektorientierten Sprache.
Objektorientiert und funktional
Die Grundlage der objektorientierten Programmierung ist die Trennung von Daten und Programm. Eine Forderung, die zu einem Dilemma führt. Selbst Java kann diese Trennung nicht vollständig gewährleisten, denn wie sollte dann ein Programm eine Klasse laden und dann die (statischen) Methoden benutzen? Ist die Klasse ein Datum, darf es keine lauffähigen Sequenzen enthalten; es fand keine Trennung von Daten (Klasse) und Programm (Methode) statt.
Spitzfindigkeiten! Ist die gängige Antwort. Nicht konsequent ist dieser Zustand aus der Sicht von Aleph. Hier gibt es in den Programmen überhaupt keine Daten. Es gibt nur funktionale Objekte. Die minimale Funktion eines solchen Objekts ist die Bereitstellung eines Wertes als Argument für die Bearbeitung. Das bearbeitende Objekt kann den Wert wieder nur als funktionales Objekt benutzen. Der einzige Ort an dem Daten (Werte) existieren ist der Stack. Programme erhalten vom Stack die Elemente aber stets in Objekte verpackt. Es ist das Erbe von LISP, das Aleph hier antritt.
Notation
Die natürliche Notation ist die aller Stackmaschinen – postfix. Diese Form stößt allgemein auf Ablehnung, denn sie gilt als schwierig zu lesen. Es stimmt; postfix-Notation ist ungewohnt und daher ist die Pflege derartiger Anwendungen aufwendig.
Die Notation herkömmlicher Programmiersprachen ist nicht infix, wie spontan angenommen. Es ist prefix. Die meisten herkömmlichen Programme nutzen diese Notation in der Form y = sin(x). Fast alle herkömmlichen Programme bestehen überwiegend aus dieser Notation. Nur wenige Zeilen enthalten tatsächlich infix-Ausdrücke.
Aleph gestattet auch die Verwendung der prefix-Notation. Der polnische Mathematiker Jan Łukasiewicz erdachte die unterschiedlichen Notationen. Ihm ist die Erkenntnis zu verdanken, dass die Notationen
- /(sin(x) cos(y))
- sin(x)/cos(y)
- y cos x sin /
gleichbedeutend sind. Die Klammerung von Termen ist bei der postfix-Notation nicht mehr erforderlich. Die Übersetzung eines prefix-Ausdrucks (1.) in einen postfix-Ausdruck (3.) besteht einfach darin, den ersten Ausdruck umzudrehen und die Klammern wegzulassen.
Programmbeispiele
Es ist immer schwierig, in einem kurzen Artikel sinnvolle Beispiele für Programme anzuführen. Deshalb ist hier kein „Hello world“-Programm vorhanden, sondern es wird ein Vergleich vorgenommen.
Fakultät berechnen
Die Berechnung von „5 Fakultät“, oder 5! erfolgt über 5 × 4 × 3 × 2 × 1. Allgemein ist der Algorithmus für n!:
Die Umsetzung in klassische Programmiersprachen ist mit
int fak ( int n) { if (n == 0) return 1; else return n * fak( n-1); }
schnell gemacht.
Aleph hat zwar Variablen, jedoch sind sie viel weiter gefasst als solche in herkömmlichen Programmiersprachen. Das Konzept von Aleph basiert auf der Vermeidung von Variablen. Die Umsetzung in Aleph kann natürlich auch mit Variablen erfolgen. Weil keine Argumentlisten existieren, muss eine Variable lokal deklariert werden. Das ist in Aleph nur indirekt möglich und führt zu folgendem Quelltext.
: fak "x" variable "x" is // Variable "lokal" deklarieren "x" find if execute endif 0 = if 1 else "x" find if execute endif // Variable suchen "ausführen" 1 - fak "x" find if execute endif * endif "x" find if forget endif // Variable "vergessen" ;
Aleph-Variablen können auch ganze Programme „enthalten“. Sie können Werte enthalten, aber auch den gesamten compilierten Code, der den Wert liefert. deshalb muss in diesem Beispiel die Variable ausgeführt werden.
Der Weg über Variablen führt bei diesem Ansatz zu unübersichtlichem Code. Aleph kann es natürlich besser. Wie bei jeder Programmiersprache muss auf die Stärken und Schwächen geachtet werden. Eine der Stärken von Aleph ist eben, Variablen nur sehr selten zu benötigen.
: fak dup 0 = if drop 1 else dup 1 - fak * endif ;
Ein Test mit
5 (long) fak .
ergibt denn auch das Ergebnis 120. Das Casting mit (long) ist erforderlich, weil Aleph stets den kleinst mächtigen Datentyp der untergeordneten Maschine (Java) wählt. Bei 5 ist das eben „byte“ und nicht „long“. Einfacher wäre
5.0 fak .
Das würde zwar dem Ansatz widersprechen (natürliche Zahlen), aber Aleph behandelt unterschiedliche Datentypen solange es möglich ist automatisch.
Schleifen
Aleph behandelt seine Commands wortgetreu. Deshalb gibt es keine „while“-, „for“- oder „do … while“-Konstruktionen. Sie können natürlich definiert werden, aber Grundlage ist der „loop“. Verlassen wird eine Schleife mit dem Command „leave“. Ist die Bedingung „wahr“, wird die Schleife verlassen.
Das folgende Beispiel zeigt eine Schleife die von 1 bis 10 zählt, jeden Schritt ausgibt und am Ende die Werte für die Abbruchbedingung auf dem Stack behält.
: count 0 // Anfangszähler loop 1 ndup 1 ndup = leave // Schleife verlassen, wenn Endwert erreicht? 1 + // Zähler erhöhen dup . " " . // Zähler ausgeben endloop "fertig " . // Hinweis auf "Ende erreicht" ausgeben ; // Bis 10 zählen und danach mit .S den Stackinhalt anzeigen 10 count .S
Die Anzeige ist
1 2 3 4 5 6 7 8 9 10 fertig Stack = [ 10 10 ]
Es ist sehr leicht, aus der Kombination von Bedingung und dem „leave“-Command alle „etablierten“ Konstruktionen von Schleifen zu erzeugen.
Einsatzgebiete und Verbreitung
Laut Auskunft des Initiators ist Aleph für Ausbildungszwecke gedacht. Ob für Anfänger oder Fortgeschrittene in der Programmierung wird allerdings nicht gesagt. Das breit angelegte Konzept der Sprache dürfte es wohl mehr für Fortgeschrittene interessant machen.
Aleph eignet sich für schnelle Entwürfe von Anwendungen. Das Zusammenspiel der oft sehr umfangreichen Klassenbibliotheken kann mit Aleph einfach und auch intensiv überprüft werden. Ob die endgültig getestete Komposition dann in einer neuen Klasse zusammengefasst wird, ist nebensächlich.
Weil in Aleph jedes Java-Element zur Verfügung steht, können sogar in C/C++ formulierte Programme in Aleph über die nativeCode-Schnittstelle von Java benutzt werden. Damit werden auch rechenintensive Anwendungen in Aleph sinnvoll.
In den großen IDEs wie Eclipse und NetBeans ist Aleph nicht anzutreffen.
Weblinks
Wikiversity: Programmieren in Aleph – Kursmaterialien, Forschungsprojekte und wissenschaftlicher Austausch
Wikimedia Foundation.