Inhaltsverzeichnis

Bevor der erste Gedanke an den Aufbau einer zukünftigen Programmiersprache gestellt werden kann, sind einige andere Fragen zu klären: es sind die prinzipiellen Regeln aufstellen, an die sich die Syntax- und Semantik-Regeln der Programmiersprache halten sollten.
Diese Grundregeln sind rein subjektiv und bestimmen eher den Charakter einer Sprache, als deren praktische Leistungsfähigkeit. Der Charakter einer Sprache kann dennoch die Leistungsfähigkeit einer Sprache beeinflussen, da er gewissermaßen den Symphatieträger zwischen Programmierer und Programmiersprache darstellt. Symphatie ist jedoch eine subjektive, nicht messbare Eigenschaft, die von jedem Programmierer unterschiedlich aufgenommen wird.

Als Beispiel sei die Programmiersprache Perl genannt, deren Syntax sich bemüht, dem Programmierer seine Ausdrucksform freizustellen. Dies zeigt sich zum Beispiel in nachgestellten Kontrollkonstrukten:

if( $a == 1 ) $b = 1;
$b = 1 if( $a == 1 );

Das macht die Sprache sympathisch für Programmierer, die sich nahe der menschlichen Sprache bewegen wollen. Programmierer, die auf eine gradlinige Syntax wert legen, reagieren hier eher ablehnend.

Die Grundregeln sollten eher als eine Zusammenfassung von bereits vorhandenen Erfahrungen und Beobachtungen verstanden werden, die beschreiben, was für diese Sprache als gut empfunden wird. Diese Grundregeln geben aber keine Wertung gegenüber Sprachen mit anderen Grundregeln.

Meine subjektive Haltung gegenüber einer Programmiersprache ist, dass sie mir nach Möglichkeit nicht negativ auffallen soll. Ich möchte meine Gedanken kurz, elegant, eindeutig und ohne Wiederholungen lesbar darstellen können, ohne dabei Sonderfälle der Sprache berücksichtigen zu müssen.

Im Umkehrschluss bedeutet dies, dass die Programmiersprache für alle wichtigen Konstrukte kurze, aber nach einem eindeutigen Muster kombinierte Anweisungen zur Verfügung stellen muss. Die Sprache sollte Redundanzen minimieren und so einen kurzen, übersichtlichen und eleganteren Aufbau des Codes zulassen und fördern. Kurze Anweisungen bedeuten auch, dass dem Programmierer möglichst viele Standard-Arbeiten abgenommen werden.
Eine Sprache fällt mir unangenehm auf, wenn sie mir den Aufbau von logisch richtigen Anweisungen verweigert, weil sich so beispielsweise Mehrdeutigkeiten ergeben, und einen Work-Around verlangt, damit ich meine Problemlösung beschreiben kann. Diese Sonderfälle verkomplizieren eine Sprache unnötig.

Dazu ergeben sich folgende Grund-Regeln, auf denen spätere Designentscheidungen basieren werden:

§1 Bedachte experimentelle Erweiterungen und Kompatibilität

Die erste Beobachtung, die hier einfließen sollte ist, dass ich eine Diplomarbeit schreibe über das Design einer neuen Programmiersprache. Dieses Thema ist nach 60 Jahren Programmiersprachen weiterhin aktuell, da sich laufend neue Programmiertechniken entwickeln, denen ältere Programmiersprachen nicht mehr vollständig entsprechen können. So wünscht sich der Entwickler mehr Unterstützung durch die Sprache und muss unter Umständen sogar die Sprache wechseln und sich in einer anderen Sprache neu einfinden.

Das C++-Standardisierungskomitee agiert sehr vorsichtig im Bezug auf Neuerungen. Neue Schlüsselwörter werden möglichst vollständig vermieden, wenn es irgendeine, wie auch immer geartete, Möglichkeit gibt, mit beliebigen Tricks auch ohne das neue Schlüsselwort auszukommen. Diese Tricks gibt es in der Regel, denn es ist möglich alle Algorithmen in C++ auszudrücken. Entsprechend gering sind die Chancen neue Konstrukte in C++ einzufügen.
Es gibt allerdings auch Schlüsselwörter und Konstrukte, die sich eher negativ auf die Sprache auswirken und nicht korrigiert werden können, um kompatibel zu vorhandenen Quelltexten zu bleiben. Ein Mailgespräch mit einem Entwickler zeigt die Erwartungen auf, die an Programmiersprachen gestellt werden: Alter K&R-Quelltext lässt sich nicht mehr mit aktuellen C-Compilern ohne Warnings kompilieren. Die Anpassung auf modernes C ist möglich, aber den passenden Compiler möchte man auch nicht mehr nutzen: Dies bedeutet zuviel unbezahlte Arbeit, so dass man die Warnings in Kauf nimmt und ignoriert.

Kompatibilität und wenig Veränderung bedeuten einerseits Verlässlichkeit, allerdings auch wenig Fortschritt und wenig Experimentiermöglichkeiten. Beides sind positive Eigenschaften, die sich in einer Sprache grundsätzlich eher ausschließen.
Die erste Regel, die daraus folgt, fordert, dass Verlässlichkeit verlangt und garantiert werden soll.
Dennoch soll die Sprache auch nach dem ersten Release lebendig und veränderlich bleiben. Selbst drastische Änderungen müssen erlaubt bleiben, wenn sie durch eine Verbesserung der Spracheigenschaften gerechtfertigt wird und der Compiler selbst von veralteten Spracheigenschaften nicht belastet werden darf.

Das bedeutet, dass nicht garantiert wird, dass der Compiler unverändert bleibt. Der Compiler und die Sprache muss jedoch erlauben veralteten Quelltext durch externe Erweiterungen vorkompilieren zu können.

Die hier entwickelte Sprache stammt von C++ ab und sollte ursprünglich hochgradig kompatibel zu C++ sein. Obwohl das Ergebnis Ähnlichkeit zu C++ besitzt und C++ leicht zu portieren ist, so ist die Sprache doch vollkommen anders als C++.
Die überlegten Erweiterungen legitimieren diesen Schritt meiner subjektiven Meinung nach. |\ Sollte ein solcher Schritt in der Zukunft wieder erforderlich werden, so dass Inkompatibilitäten entstehen, sind diese durch den Grundsatz legitimiert, dass Fortschritte zur Verbesserung wichtiger als uneingeschränkte Kompatibilität zum eigentlichen Compiler, bzw. zur eigentlichen Sprache sind. Es muss lediglich eine Möglichkeit existieren, zur nächst höheren, nicht mehr kompatiblen Sprachversion umkompilieren zu können.

Diese Grundregel legitimiert damit den Einbau sinnvoller Erweiterungen und Änderungen und damit ein aktives Leben der Sprache für Verbesserungen und garantiert Kompatibilität auch zu veralteten Versionen.

§2 keine Spezialisierung

Unter dem Begriff 'nicht spezialisierte Sprache' lassen sich Sprachen zusammenfassen, welche für keine festgelegte Aufgabe entwickelt wurden, sondern grundsätzlich eine beliebige Aufgabe irgendwie lösen können. Die beliebige Aufgabe kann die Erstellung von Webseiten darstellen, schnellen mathematischen Berechnungen oder kurzen Skripten, um kleine Aufgaben zu lösen. Durch das „irgendwie zu lösen“ spezialisierten sich unterschiedliche, „nicht spezialisierte“ Sprachen wieder auf speziellere besondere Probleme. Kompilierende Sprachen bearbeiten rechenintensive Aufgaben, interpretierende Sprachen bearbeiten Skripte und erstellen Webseiten. Syntaktisch unterschiedliche, „nicht spezialisierte“ Sprachen spezialisieren sich auf ihre Einsatzgebiete, so dass sich auch die Programmierer entsprechend ihres Einsatzgebietes spezialisieren müssen oder mehrere Sprachen gleichzeitig beherrschen müssen.
Realistisch betrachtet ist damit die Mehrzahl der Entwickler Experte in einer Sprache für ein Spezialgebiet oder sie verfügen über Kenntnisse in mehreren Sprachen, ohne eine Sprache optimal nutzen zu können.

Das Resultat bedeutet, dass die Programmiersprachen Einfluss darauf haben, ob ein Entwickler auf ein Spezialgebiet begrenzt einsetzbar ist oder allgemeiner einsetzbar, aber dafür wahrscheinlich nicht optimale Programme liefern kann.

Die Leistung eines Entwicklers kann also gesteigert werden, wenn er sich auf eine Sprache spezialisieren kann, die selbst mehrere Gebiete abdecken kann. Dies ist nur möglich, wenn die Sprache selbst möglichst wenige Vorgaben liefert. So sollte die Entscheidung, ob ein kleines Skript zu einer ausführbaren Datei kompiliert werden muss oder sofort interpretiert werden kann, also nicht durch die Sprache vorgegeben sein, sondern bedarfsgerecht durch den Entwickler entschieden werden.

§3 Orthogonalität

Orthogonalität kann man kurz so zusammenfassen, dass die Programmiersprache sich mit jedem Ausdruck wieder in einem für den Programmierer einfach nachvollziehbaren Zustand befindet. Das bedeutet zum einen, dass eine Programmiersprache nach Möglichkeit so wenige Zustände besitzt, so dass auch ein Einsteiger schnell alle Zustände erfassen kann. Zum anderen dürfen keine Zweideutigkeiten entstehen, die die Sprache unbeabsichtigt in einen eventuell nicht gewünschten Zustand versetzt. Das Verlangen nach Orthogonalität erscheint so selbstverständlich, dass eine so hohe Priorität ungewöhnlich erscheint. Leider ist die Umsetzung nicht so einfach, als dass Orthogonalität selbst bei den erfolgreichen Sprachen zu erwarten wäre. Dies ist am einfachsten durch ein paar Beispiele ersichtlich.

In JavaScript findet sich folgendes Rätsel:

var myVar = "Hallo 1234 World";
var n = 0, c;
 
for( n=0; n < myVar.length; n++ )
{
  c = myVar.codeAt( n );
  if( c == 'o' ) alert( 'Character '+c+' gefunden' );
  if( c ==  2  ) alert( 'Ziffer '+c+' gefunden' );
  if( c == '3' ) alert( 'Character '+c+' gefunden' );
}

Führt man diese Schleife aus, erhält man erwartungsgemäß drei Alerts. Diese melden „Character o gefunden“, „Ziffer 2 gefunden“, „Character o gefunden“. Da hier ASCII-Werte verglichen werden sollten, kommt der Wert 2 eigentlich nicht im String „Hallo 1234 World“ vor, nachvollziehbar wäre ein Alert „Character 3 gefunden“ gewesen, der aber wiederum nicht auftritt. Es findet für die ASCII-Zeichen 48-57 ('0'-'9') eine Konvertierung statt, die dabei die Werte 0-9 mit den ASCII-Zeichen 0-9 und den Ziffern 0-9 doppelt belegt.
Seine Meisterprüfung legt JavaScript jedoch mit dem Plus-Operator ab:

var temp = window.prompt( “Bitte Zahl eingeben“ );
temp += 2;
window.alert( temp );

Ergebnis: Gibt man die Zahl 10 ein und lässt darauf 2 aufaddieren, dann ist das 102. Das ist logisch, aber zunächst eher unerwartet. Das Beispiel hier ist leicht zu durchschauen, da window.prompt einen String zurückliefert. Da JavaScript jedoch nicht typsicher ist, können bei verzweigten Algorithmen fragliche und schwer zu findene Fehler auftreten.

Orthogonalität setzt sich fort im Aufbau des Sourcecodes. Hier werden nicht mehr Ausdrücke aneinandergereiht, sondern hier treten unerwartete Phänomene bei unterschiedlichen Konstrukten auf. Die Pascal-Programmierer liegen mit Ihrer Anmerkung der seltsamen Semikolons bei C richtig. Das Semikolon bedeutet üblicherweise, dass eine Anweisung vollständig ist:

  if( a == 1 ) do_anything();
  else         do_anything_else();

Nach do_anything() folgt ein Semikolon, obwohl das Konstrukt durch „else“ noch erweitert wird. „else“ ist in C, C#, Java, JavaScript, PHP […] kein eigenständiges Konstrukt und steht hier doch hinter einem Semikolon. Das widerspricht der Logik der Sprache, diese Sprache ist damit nicht orthogonal, bzw. es liegen Schwächen vor.

Leichtes Spiel bietet sich bei den Operatoren:

C++ benutzt für Templates folgende Syntax, um ein eine Liste vom Typ X zu gestalten:

  template<class X> class MeineListe { };

Um eine Liste von Listen von Integern zu deklarieren schreibt man

  MeineListe<MeineListe<int>> MeineIntegerListenListe;

und hofft, dass die lexikalische Analyse des Compilers versteht, dass nach dem 'int' kein '»'-Operator gemeint ist.

Wer sicher gehen möchte muss die Umklammerung aufsplitten.

  MeineListe<MeineListe<int> > MeineIntegerListenListe;

Allgemein lassen sich mit aufeinander folgenden Operatoren schnell Ungereimtheiten in die Sprache einbauen. Hierzu wird in einem späteren Kapitel ein entsprechendes Beispiel gegeben. (siehe Kapitel 5, Kombination der Bausteine Funktionen, Operatoren, Properties und Variablenzugriff)

Durch diese Reihe von Beispielen zeigt sich, dass Orthogonalität in einer Sprache ein großes und weites Gebiet abdeckt und alles andere als ein leicht zu erreichendes Ziel darstellt.

„Orthogonalität ist allerdings kein primäres Ziel, sie wird immer dann angestrebt, wenn sie nicht mit anderen Regeln im Konflikt steht und Vorteile bietet, ohne die Implementierung zu komplizieren.“, schreibt Bjarne Stroustrup[1, S.142] über seine Herangehensweise bei C++.
Sprachen, wie C++ existieren bereits, der nächste Schritt wäre zu prüfen, ob sich für eine Programmiersprache ein Regelsystem finden lässt, dass Orthogonalität gewährleistet.

Fehler im Konzept zeigen sich oft erst Jahre später, so kann man lediglich aus den gemachten Erfahrungen Schlüsse ziehen und sich darum bemühen, auf diese Fehler zu achten und bekannte Fehler nicht zu wiederholen.
Alle gezeigten Beispiele stellen Fehler bzw. Schwächen von Sprachen dar, die als Sonderfälle unangenehm in der Programmierung auffallen und vom Einsteiger in der Regel Fall für Fall selbst erfahren werden müssen.
Weitere Beispiele werden an passender Stelle folgen.
Die Forderung nach Orthogonalität bedeutet also auch weniger Sonderfälle und damit mehr Motivation beim Erlernen der Sprache, sowie eindeutige und interpretationsfreie Anweisungen.
Weniger Sonderfälle bedeuten auch eine vereinfachte Implementierung.

§4 Einheitliche Darstellung von Sachverhalten

Programmiersprachen entwickeln sich nach Ihrer ersten Veröffentlichung weiter. In der Regel wachsen sie in Ihren Bereich hinein und passen sich bekannten ähnlichen Programmiersprachen aus diesem Bereich an. Ebenso begann die Planung zu diesem Projekt bei C++.

Als Beispiel sei die Zuweisung von konstanten Variablen innerhalb einer Klasse genannt. Eine normale Variable wird mit

int var = 4;

zugewiesen. Eine Konstante mit

int var const = 4;

Innerhalb einer Klasse ist eine Konstante erst gesetzt, wenn die Instanz erzeugt wird. Sie muss vor der Ausführung des Konstruktors initialisiert werden, allerdings mit einem Wert, die dem Konstruktor bekannt sein muss. Die Variable wird somit in die Initialisierungsliste aufgenommen und entsprechend dem Aufruf für einen anderen Konstruktor initialisiert:

class foo
{
  int const var;
 
  foo( int Wert ) : var(Wert)
  {
    // Konstruktor
  }
};

Diese Form der Zuweisung sieht damit syntaktisch wie ein Funktionsaufruf aus.

Diese Regel könnte auch als „optische Orthogonalität“ bezeichnet werden, da die Sprache hier für beide Fälle eindeutige und interpretationsfreie Regeln besitzt. Beide Fälle sind sich allerdings sehr ähnlich, und sollten für den Programmierer ebenfalls einfach optisch gleichwertig behandelt werden.
Diese Regel dient dazu, sich nicht an Bekanntem festzuklammern, sondern durchaus auch neue Alternativen zu suchen.

§5 Individuelle Programmierung vor geleiteter Programmierung

Hier möchte ich meinen Betreuer im Praxissemester heranziehen, der sich von einer Programmiersprache eine gewisse Führung wünscht, so dass Standardprobleme auch mit möglichst genau einer Lösung versehen sind, die von jedem Programmierer verwendet wird. Der Vorteil dabei ist, dass Quelltexte sich ähneln und somit leichter zu verstehen und untereinander auszutauschen sind.
Dabei ergibt sich der Nachteil, dass sich jeder Programmierer, unabhängig von seinen eigenen Vorlieben, den Vorlieben des Sprachenimplementierers anzupassen hat. Das widerspricht zum einen meiner persönlichen Vorliebe, meiner Freude am Experimentieren und der Erfahrung, dass sich durch das Experimentieren regelmäßig bessere Lösungen finden lassen, als die bereits Vorhandenen. Diesen Prozess irgendwann abzubrechen, um Anwendungsprogrammierung zu vereinfachen, widerspricht der Grundidee eine nicht spezialisierte Sprache zu definieren.

Wie jeder Programmierer, bin ich davon überzeugt, den besten Weg zu programmieren gefunden zu haben – sonst würde ich anders programmieren. Genauso denkt vermutlich jeder anderer Programmierer ebenfalls und sollte dementsprechend die gleichen Möglichkeiten haben, sich in der Sprache auszudrücken.

§6 Programmierer sind intelligente Menschen

Auch die folgende, subjektive Einschätzung wird nicht von jedem Entwickler geteilt, dennoch ist grundsätzlich zu unterstellen, dass eine Person, die sich mit Programmierung auseinandersetzt, intelligent sein dürfte. Unter der Zielsetzung, dass der Entwickler sich auf eine Sprache spezialisieren kann, kann er in dieser einen Sprache Expertenwissen ansammeln und somit bewusst auch „gefährlichere“ Ausdrücke formulieren, um elegantere, aber trickreichere Algorithmen zu formulieren.

Ein intelligenter Mensch wird immer Mittel und Wege suchen, Verbote und Gebote so zu umgehen, dass der von ihm gewünschte Effekt erzieht werden kann. Wer Verbote nicht umgehen kann, sie aber umgehen möchte, der wählt notfalls eine andere Programmiersprache, die ihm die gewünschte Freiheit lässt. Das widerspricht wiederum dem Ziel, eine Sprache für möglichst viele Anforderungen zu bieten.
Mangelnde Freiheiten sollten nicht der Grund sein, die Programmiersprache zu wechseln.

Ich ziehe die Konsequenz daraus, gar nichts zu verbieten.
Das bedeutet, dass alles, was der Programmierer zu tun wünscht, ihm auch auf Wunsch ohne Störung durch den Compiler erlaubt wird, sofern es syntaktisch und semantisch korrekt ausgedrückt werden kann.
Einen guten Programmierstil kann man fördern, aber nicht durchsetzen. In jeder Sprache wird schlecht lesbare und schlecht strukturierte Programme geschrieben.

§7 Keine vorgeschriebene Formatierung

Beschäftigt man sich mit dem Aufbau von Quelltexten, so finden sich eigentlich nur zwei Möglichkeiten einen Quelltext aufzubauen. Entweder man lässt den Programmierer machen, was er möchte, wie es in C, Java usw. gehandhabt wird oder man gibt ihm ein Format vor, dass er zu befolgen hat, wie es Assembler oder Fortran der Fall ist, so dass zum Beispiel in jeder Zeile genau eine Anweisung steht.

Letztere Sprachen werden heute eher in Ausnahmefällen benutzt und die Vorgabe, dass in einer Zeile genau eine Anweisung stehen muss, widerspricht zunächst offensichtlich der Regel, dass man seine Algorithmen nach eigenem Wunsch formulieren können sollte und behindert die Umsetzung von Erweiterungen.

Eine saubere Formatierung lässt sich bei der Erlaubnis eines individuellen Programmiererstils problemlos durch einen Style-Guide erreichen und jede beliebige Formatierungsvorlage läßt sich soweit missbrauchen, dass Quelltext unlesbar wird. Der saubere Aufbau eines Quelltextes kann eine sehr große Hilfe sein, aber nur, wenn der Programmierer diese Strukturierung gewohnt ist und gut lesen kann. Einem Programmierer vorzugeben, was er gut lesen können sollte, kann ein Angebot sein, sollte aber keine Verpflichtung darstellen.

§8 Zurückhaltung bei implizierter Funktionalität

Implizierte Funktionalitäten, wie zum Beispiel das Vorinitialisieren von Variablen mit Nullwerten sorgen dafür, dass dem Programmierer eine nicht initialisierte Variable wahrscheinlich(!) keine Probleme bereitet. In jedem Fall entstehen bei einer durch die Sprache implizit vorinitialisierten Variable keine willkürlichen Fehler, sondern reproduzierbare, die eventuell leichter zu finden sind. Eine nicht initialisierte Variable kann allerdings auch Werte erzeugen, die so bemerkenswert falsch sind, dass sie sofort auffallen. Der Code wird nicht richtiger - unabhängig davon, ob die Variable implizit vorinitialisiert wurde oder nicht.

Die zu entwickelnde Sprache darf selbstständig implizite Eingriffe tätigen, sofern diese dringend notwendig sind, sollte jedoch den Programmierer Einwände haben, muss jegliche implizierte Funktionalität abschaltbar sein.
Was dringend notwendig ist, entscheidet am Schluss der Entwickler.
Mit diesen Regeln ist die zu entwickelnde Sprache - obwohl sie noch keinerlei Festlegung besitzt - schon deutlich eingegrenzt. Die mir bekannten Programmiersprachen entsprechen den oben genannten Regeln bereits nicht mehr.

§9 kein Informationsverlust

Jede Information, die der Compiler im Verlauf einer Rechnung entwickelt, sollte vom Entwickler abfragbar sein in Wert (je nach Datentyp) und Wahrheitswert (boolescher Wert) abgefragt werden können.
Das bedeutet, dass beispielsweise der Vergleichsoperator einerseits den Wahrheitswert zurückliefern können sollte, aber die Möglichkeiten existieren sollte, den verglichenen Wert zu erhalten, um damit weiterzurechnen oder null zurückzuliefern.
Hierdurch entstehen neue Operatoren und entsprechend neue Ausdrucksmöglichkeiten.

§10 Resourcenverwaltung

Diese Regel ist lässt sich kurz beschreiben: es ist darauf zu achten, dass Arbeitsspeicher möglichst zur Verwaltung des Programms sparsam verwendet wird. Auch ist darauf zu achten, dass möglichst wenig Rechenzeit verbraucht wird, um optimale Performance nicht durch die Sprache zu verhindern. Das bedeutet, dass dynamische Prüfungen nach möglichst zu verhindern sind und nach Möglichkeiten von statischen Prüfungen soweit wie möglich ausgeschöpft werden.

Weitere Festlegungen

Ohne eine Festlegung zu treffen, folgt nun die Konkretisierung der Sprache.

In welchem Bereich wird die Sprache zukünftig zum Einsatz kommen?

Wird eine Sprache für einen besonderen Bereich geschrieben, so handelt es sich um eine spezialisierte Sprache. Ziel dieser Arbeit ist es, eine nicht spezialisierte, also allgemeine Programmiersprache zu entwickeln. Diese Absicht verfolgten viele andere Programmiersprachen ebenfalls (vergleiche Vorwort [7]: „C++ ist eine allgemein verwendbare Programmiersprache. Sie wurde erfunden, damit der professionelle Programmierer mehr Vergnügen an seiner Arbeit hat.“ ), dennoch wird C/C++ heutzutage vorrangig in der systemnahmen Programmierung benutzt. Anwendungsprogrammierer weichten mehr auf VisualBasic und Java aus, beziehungsweise C#.
Für Websites hat sich serverseitig PHP und ASP (VisualBasic und C#) verbreitet, für Scripting liegen Perl, PHP, Python, Visual Basic for Applications, Rexx sowie die einfache Batch/Shell Programmierung etabliert. Skripting auf Client-Seite im Webbrowser funktioniert ausschließlich über JavaScript, über Plug-Ins lässt sich noch Flash, Java und ähnliches nachinstallieren.

Viele der Sprachen sind recht allgemein gehalten, keine ist allgemein genug, um überall mitspielen zu können.
Ziel von Genesys ist es eine Sprache für möglichst viele Bereiche anzubieten, ohne dass der Programmierer für seinen Einsatzzweck Work-Arounds benötigt, ein projektabhängiger Wechsel der Programmiersprachen sollte nicht mehr erforderlich sein.
Die Frage nach einem spezialisierten Bereich stellt sich sogesehen nicht, die hervorzuhebenden Eigenschaften der wichtigen Sprachen sind also zu sammeln und in einer einzigen Sprache zu vereinen.

Erlaubt sind allerdings Erweiterungen, die nicht spezialisiert sind, sich gegebenenfalls aber positiv für einen Spezialfall auswirken.

Für welchen Programmierer wird die Sprache ausgelegt?

In der Entwicklungszeit von C++, war die Sprache sehr beliebt, weil sie einfach zu erlernen war. Diesbezüglich gelten heutzutage andere Maßstäbe. Dennoch halte ich diese Herangehensweise für richtig. Die zu entwickelnde Sprache sollte mit wenigen sprachlichen Mitteln bereits produktiv zum Einsatz kommen können, so dass ein Anfänger oder Skriptprogrammierer sich nicht um Funktionen oder Klassen kümmern muss. Dennoch dürfen Funktionen und Klassen natürlich nicht fehlen. Die Sprache muss in der Lage sein, den Anfänger abzuholen und bis zum Experten zu begleiten. Da die Leistung von C++ erreicht werden soll, wird die Komplexität mindestens genauso hoch sein, wenn alle Möglichkeiten der Sprache vollständig ausgeschöpft werden.

Soll die Sprache besondere Schwerpunkte legen und wenn ja, welche sollen das sein?

Da Genesys nicht speziell ausgelegt wird, ist der erste Schwerpunkt die Übernahme der Funktionalität der vorhandenen nicht spezialisierten Sprachen. Das bedeutet Ausdrücke, Funktionen, Klassen, Mehrfachvererbung, virtuelle Funktionen, Arrays, Listen, RTTI, Templates, Komponenten, Stringverarbeitung, Einbinden von Daten, reguläre Ausdrücke, Arrays, Listen und Iteratoren beschreiben die Mindestanforderung.
Diese Funktionalität alleine würde eine neue Programmiersprache rechtfertigen, da die jüngste Sprache C# mit Ihrem Funktionsumfang bereits nicht mehr in dieser Liga spielt.

C brachte leistungsfähige, und vielseitige Operatoren in die allgemeine Programmierung, C++ leistete durch virtuelle Funktionen die Umsetzung von objektorienter Programmierung in der Allgemeinheit.
Aktuelle Sprachen wie Java und C# stellen sich allerdings vorrangig als Erben von C++ dar, sind jedoch in Ihrer Funktionalität eingeschränkt worden und bieten stattdessen einen großen Umfang an Bibliotheken und Komponenten. Nennenswerte Erweiterungen oder Neuerung haben die Sprachen nicht erhalten, lediglich die Verwendung von bereits kompilierten Komponenten wurde in beiden Sprachen vereinfacht und die Garbage Collection erleichtert teilweise die Entwicklung. Auf die möglichen Freiheiten bezogen, bietet C++ derzeit die meisten Möglichkeiten. Diese wirken sich direkt auf die Leistungsfähigkeit der Programme aus. Im Hinblick auf die Leistungsfähigkeiten ist C++ damit immer noch die meineserachtens am weitesten fortgeschrittene Sprache.