dot hat geschrieben:Ich denk bevor man hier beginnen kann zu diskutieren, müsste man erstmal die Grundphilosophie dieser hypothetischen neuen Sprache erklären.
Ohne irgendwelche Design Goals fehlt der Diskussion jegliche Grundlage...
Also: Was genau willst du mit dieser Sprache erreichen?
Prinzipiell geht es um einen Entwurf für eine allgemeingültige Sprache, die nicht nur für spezielle Zwecke nützlich ist, sondern auch global zum Einsatz kommen kann. Erreichen möchte ich in erster Linie, dass die guten Aspekte vorhandener Sprachen kombiniert werden, eventuell neue Features hinzukommen und Aspekte eliminiert werden, die Nachteile bringen, eventuell Performance einbüßen oder die Lesbarkeit/Wartbarkeit verschlechtern. Das sind aber nur Beispiele. Es geht wie gesagt nicht mal so sehr darum, ob diese Sprache jemals entwickelt wird, sondern um eine Zusammentragung von Ideen, Erfahrungen, Wünschen, usw. In diesem Forum gibt es sehr viele begabte Programmierer, wo also sonst könnte man besser darüber philosophieren und diskutieren?
Florian Keßeler hat geschrieben:C. Ich mag es eigentlich nicht, Konventionen fest vorzugeben, weil sie irgendwem grundsätzlich nicht passen. Aber andererseits hat es Vorteile, wenn man sich nicht bei jedem Projekt in neue obskure Vorgaben einarbeiten muss.
Eben aus dem letztgenannten Grund bin ich eigentlich eher für festere Vorgaben. Man denke nur an so Sachen wie CMyClass, wo selbst heute noch einige Programmierer denken, dass das 'C' am Anfang Pflicht bei Klassen ist. Hätte man eine strikte Regel, wäre es halt recht eindeutig. Wenn sich alle Bezeichner in einer bestimmten Form unterscheiden, würden einige Doppeldeutigkeiten beseitigt werden. Man denke nur an sowas:
Code: Alles auswählen
class apple { };
apple apple; // shit I have to rename it to _apple or something like that
Selbst wenn man Hilfestellungen nimmt bei dem man das bei der Deklaration unterscheiden kann, so kann es im weiteren Verlauf dennoch zu Ungereimtheiten führen. Ist es nun der Klassenname oder ein Objekt? Ganz zu schweigen von Operationen die eventuell auf beidem Arbeiten können und dann vielleicht sogar das falsche angenommen wird.
Und man hat einfach eine einheitlichere Struktur, die das Lesen von Code für jeden Programmierer vereinfacht und vielleicht auch das automatisierte Auswerten von Code und die Arbeit des Compilers/Parsers vereinfacht.
Florian Keßeler hat geschrieben:D. ... Daten außerhalb von Klassen würde ich persönlich aus verschiedenen Gründen verbieten, freistehende Funktionen allerdings nicht. Ich finde es ziemlich unnatürlich, wie es z.B. bei Java gehandhabt wird. Eine Klasse zu haben, aus der bei Programmstart eine statische Methode aufgerufen wird... dann doch lieber direkt aufrufen, außerdem erlaubt es teilweise mehr Kapselung, freistehende Funktionen zu haben, die nur öffentliche Methoden von Objekten benutzen anstatt Memberfunktionen zu nutzen, die direkt auf die privaten Daten zugreifen könne.
Sehe ich genauso. Dieses "Alles-gehört-in-eine-Klasse"-Konzept widerstrebt mir und wie du schon sagtest können globale Funktionen die Kapselung erhöhen. Es ist einfach sinnlos Funktionen in Klassen zu packen, nur damit man alles in Klassen hat. Global kann ja auch namespace-lokal bedeuten, prinzipiell auch mit einem globalen Namespace oder Root-Namespace.
Florian Keßeler hat geschrieben:E. Macros und Präprozessor würde ich komplett weglassen. Ein Templatesystem wie in C++ kann fast alles, was man sich zur Compilezeit wünschen kann. Alle Sachen, für die man in C++ zwingend noch den Präprozessor braucht kann man einfach weglassen (Includeguards z.B. in dem man ein "echtes" Modulsystem anbietet, ohne Includedateien)
Ich bin auch kein Freund vom Präprozessor. Er mag für bestimmte Aufgaben (z.B. Textersetzung) geeignet sein, aber er bringt einfach viel zu viele Nachteile mit sich (keine Debugmöglichkeit, Verschleierung von Abhängigkeiten, usw), als dass er in modernen Sprachen noch Anwendung finden sollte. Ich hab es trotzdem zur Diskussion gestellt. Vielleicht hat ja auch jemand andere Argumente oder kann einen "guten" Präprozessor skizzieren. Templates find ich auch wichtig, aber eventuell sind sie noch verbesserungswürdig (von C++ ausgehend). Es gibt ja auch noch so Sachen wie Concepts usw. Hab da leider zu wenig Erfahrung um was Produktives beizutragen denk ich.
Florian Keßeler hat geschrieben:F. Eine gute Sprachdefinition sollte alles das können. Haskell lässt sich z.B. hervorragend Interpretieren (ghci) oder auch übersetzen (ghc). Nur mit dem Ausführen auf z.B. der Java VM tut Haskell sich schwer, liegt aber so weit ich weiß eher an der Java VM als an der Sprachdefinition. Zwecks Anbindung an bestehende Compilerframeworks würde ich sogar einen Zwischencodegenerator bevorzugen, so bekommt man einige Lowlevel-Optimierungen und Platform-Portierungen umsonst.
Naja ich weiß nicht so recht. Wenn etwas interpretierbar ist, habe ich immer die Befürchtung, dass es dann in kompilierter Binärform nicht so leistungsfähig ist, wie eine rein kompilierbare Sprache. Aber das ist sicher eine Designfrage. Ich will diesen Punkt aber auch deshalb mit als Denkanstoss nutzen, indem man vielleicht auch mal philosophiert, was man beachten muss, wenn beides möglich sein soll und beides ein recht effektives Programm erzeugt.
Florian Keßeler hat geschrieben:H. Wenn man weiß, wie viele Probleme Threaderzeugung und Synchronisation bei C++ gemacht haben, bevor es irgendwann plattformübergreifende Bibliotheken dafür gab (z.B. Qt), sollte man sowas direkt in die Sprache einbauen. An der Stelle könnte man auch über sowas wie atomare Blöcke, lockfreie Datenstrukturen und ähnlichem Nachdenken und wiefern sich deren Vorhandensein direkt in der Sprache (statt in einer Bibliothek) vielleicht positiv auswirken könnte.
Ich hatte mir mal folgendes überlegt. Da ein Thread ja eigentlich immer mit einer Funktion verknüpft ist, könnte man ja einen Thread auch direkt als eine abgewandelte Funktion definieren. Etwa in der Form:
Code: Alles auswählen
thread MyThread(int arg)
{
...
}
MyThread my_thread;
my_thread.start();
while (my_thread.running)
...;
Sonst hat man immer den Thread als Objekt und die Einsprungsfunktion separat. Ist vielleicht auch eine Philosophiefrage aber ich finds einfach umständlich ein Threadobjekt und noch eine Extrafunktion anzulegen.
Florian Keßeler hat geschrieben:I. Einrückung als Sprachmittel finde ich bei Haskell und Python eigentlich sehr angenehm. Es spart auch die lästige Frage danach, wo die geschwungenen Klammern hinkommen und zwingt Programmieranfänger dazu, sich über Verschachtelung Gedanken zu machen. Operatorüberladung finde ich, trotz allen Misbrauchs, der damit getrieben wird, sehr gut, weil sie eben auch sehr elegante Arbeitsweisen erlaubt.
Ich bin geteilter Meinung. Ich finde es recht gut innerhalb von Blöcken immer eine passende Einrückung vorzuschreiben, aber ganz ohne geschweifte Klammern oder ähnlichem auszukommen, kann schon etwas unübersichtlich werden. Es fehlen die klaren Grenzen, z.B. bei Klassen, Namensräumen usw. Und falls Schleifen-Bodies mal länger werden gilt dort das gleiche. Prinzipiell finde ich aber die Einrückung schon gut. Z.B. ist eine Klasse im Namespace um eins weiter eingerückt und Member der Klasse wiederum eins weiter usw. Auch dies trägt mMn extrem zur Lesbarkeit und Übersicht bei.
Florian Keßeler hat geschrieben:J. Streams sind wohl mehr oder weniger der Default für I/O aller Art geworden. Ein einheitliches Interface für alle Arten von I/O ist natürlich schön (wie es z.B. UNIX seit jeher anbietet). Eingebaute Sprachfeatures für asynchrone I/O wären sicher auch nicht zu verachten.
Mit gefällt eine transparente/flexible/austauschbare Schnittstelle für lokale I/O, Pipes und Netzwerkdaten sehr gut. Wenn ich dran denke, dass ich in C++ direkt per Stream-Operatoren von einem Socket lesen oder schreiben kann, wär das schon ne tolle Sache. Auch in Hinblick auf verteilte Applikationen/Systeme.
Florian Keßeler hat geschrieben:R. Ein echtes Modulkonzept hat eigentlich nur Vorteile gegenüber dem Headerdatei/Namespace-Mischmasch von C++. Außerdem sind zwei getrennte Dateien für Deklaration und Definition irgendwie Banane. Ich würde da also auch eher den Java/Python/fast-alles-außer-C-Weg gehen.
Ich sehe auch nur Vorteile. Allerdings haben da vielleicht andere Leute auch noch andere Meinungen zu. Mal abwarten.
Florian Keßeler hat geschrieben:T. Finde ich gut. Bis auf die Parse-Funktionen. Die gehören da imho nicht rein, sondern als Operator o.ä. an die Streamobjekte gekoppelt, wie es halt auch bei C++ schon ist.
Das waren nur Beispiele. Ich finde solche Dinge aber auch angenehm. Die Form ist ja erstmal egal, aber das sind ja in der Regel sogar statische Daten, die zur Compilezeit bekannt sind. Meine Idee wäre, dass es TypeTraits direkt auf den Typ gibt, aber auch für konkrete Objekte des Typs. Z.B. ein length() auf einen String oder ein dynamisches Array usw. Dabei muss man natürlich erstmal festlegen ob String und Arrays Teil der Sprache sind oder Bestandteil einer Library. Aber man kann ja auch an Dinge wie
if (5.typename() == "int") denken und so Sachen. ;)
Ohne Input kein Output.