Wenn man eine Programmiersprache des 21. Jahrhunderts erfindet

Der Autor des Artikels diskutiert die Probleme moderner Programmiersprachen und die Möglichkeiten, Mängel zu beheben.


In den letzten 18 Jahren haben sich viele Sprachen ausgedacht, von denen Swift, Kotlin und Go wahrscheinlich die beliebtesten sind. Gleichzeitig ist das Unterscheidungsmerkmal der Programmiersprache des 21. Jahrhunderts das Fehlen jeglicher Unterscheidungsmerkmale. Das Schönste an der Arbeit mit solchen Sprachen ist, dass Sie ein Wochenende damit verbringen können, eine dieser Sprachen zu lernen, und schließlich sagen, dass Sie es geschafft haben, eine beliebte Neuheit zu lernen, aber tatsächlich haben Sie nichts Neues gelernt. Sie sind wirklich nichts Neues. Alle modernen Sprachen werden auf der Grundlage einer korrekten und bewährten Formel erstellt, deren Name höchstwahrscheinlich Objective-C, Java oder C lautet.

"Mangel an Neuheit" kann als wertvolles Merkmal angesehen werden, aber diese Situation wirft eine Frage auf. Stehen wir wirklich vor den Sprachen des neuen 21. Jahrhunderts oder spiegelt dies nur die schlechten Programmiergewohnheiten des 20. Jahrhunderts wider?

Wenn ich die Sprache erfinden würde, würde ich nicht versuchen, die Vergangenheit zu korrigieren, sondern etwas schaffen, das unter modernen Bedingungen gut funktioniert, aber auch in der Lage ist, den Test der Zeit zu entwickeln und zu überstehen. Wenn dies radikale konstruktive Lösungen erfordert, dann sei es so.

Nieder mit der Syntax!


Die Syntax moderner Sprachen spiegelt den Versuch wider, die Freiheit von Kreide und Tafel in die Fesseln von ASCII zu drücken. Einige Elemente eines Datensatzes, wie z. B. arithmetische Zeichen oder Klammern, werden mehr oder weniger natürlich wahrgenommen. Eine Reihe anderer Bezeichnungen ist jedoch nur durch Einsparung von Aufwand beim Drücken der Teletyp-Tasten gerechtfertigt.

Die Eingabe von Text über die Tastatur ist nicht mehr schwierig. Wir müssen uns nicht in eine Position bringen, in der es notwendig ist, die Bedeutung der Syntax zu erraten. Stücke wie (($: @ (<# [), (= # [), $: @ (> # [)) ({~? @ #)) ^: (1 <#) - ein sehr kurzes und umfangreiches Aufnahmeformat (Dies ist übrigens ein echtes Stück Code in echter Sprache ), aber es verbessert in keiner Weise die Lesbarkeit. Und was noch wichtiger ist, es ist schwierig, es zu "googeln" oder im Stackoverflow zu finden.

Gleiches gilt für die mysteriösen Namen von Funktionen, Konventionen von Rückkehrcodes und Attributen mit unklarer Bedeutung. Sie haben in der Vergangenheit gute Dienste geleistet und viel Platz auf Lochkarten gespart, aber heute ist es Zeit für eine wohlverdiente Pause.

So etwas wie

FILE * test_file = fopen("/tmp/test.txt", "w+");

sollte umgewandelt werden in

create file /tmp/test.txt for input and output as test_file

Wir brauchen nicht alle diese Klammern, Anführungszeichen, Sternchen und Semikolons (es sei denn, sie vermitteln die Idee wirklich nicht klarer). Die Syntaxhervorhebung kann die Syntaxnotation vollständig ersetzen.

Im 21. Jahrhundert gibt es einige reichlich vorhandene Dinge: zum Beispiel Analysegeschwindigkeit, Computerspeicher, Online-Suche. Andere Ressourcen sind noch im Preis: Entwicklungszeit, Speicher des Programmierers, Aufwand für das Erlernen der Merkmale der Sprache. Änderungen an den Regeln für das Schreiben von Code sollten den Fokus auf billigere Ressourcen verlagern und teurere einsparen.

Nieder mit den eingebauten Typen!


Sie sind wahrscheinlich mit JavaScript-Paradoxien vertraut. Zum Beispiel:

> 10.8 / 100
0.10800000000000001


Dieses Ergebnis gilt nicht nur für JavaScript. Und dies ist überhaupt kein Paradoxon, sondern ein Beispiel für die absolut korrekte Einhaltung des anerkannten IEEE 754-Standards. Eine ähnliche Implementierung von Gleitkommazahlen findet sich in fast allen Architekturen. Und es ist nicht so schlimm, wenn man bedenkt, dass wir versuchen, eine unendliche Anzahl von reellen Zahlen in 32, 64 oder 256 Bit zu packen.

Was Mathematiker für unmöglich halten, verkörpern Ingenieure durch die Ablehnung des gesunden Menschenverstandes im Interesse der praktischen Umsetzung. Die Gleitkommazahlen in der IEEE-Interpretation sind überhaupt keine Zahlen. Mathematik erfordert Assoziativität aus der Operation ihrer Addition. Die Typen float und double speichern diese Eigenschaft nicht immer. Für die Mathematik ist es erforderlich, dass die Menge der reellen Zahlen Ganzzahlen enthält. Diese Anforderung wird jedoch auch für float und uint32_t derselben Größe nicht erfüllt. Mathematik erfordert, dass reelle Zahlen ein Nullelement haben. In dieser Hinsicht übertrifft der IEEE-Standard alle Erwartungen, da Gleitkommazahlen zwei Nullelemente anstelle von einem haben.

Nicht nur Gleitkommazahlen weisen ähnliche Merkmale auf. Eingebettete Ganzzahlen sind nicht besser implementiert. Wissen Sie, was passiert, wenn Sie versuchen, zwei solche 16-Bit-Zahlen hinzuzufügen?

0xFFFF + 0x0001

Niemand wird eine genaue Antwort geben. Ein Instinkt sagt uns, dass ein Überlauf 0x0000 ergibt. Ein solches Ergebnis ist jedoch in keinem internationalen Standard dokumentiert. Bei der Handhabung dieses Vorgangs orientiert sich jeder am C-Ansatz und an der x86-Prozessorfamilie. Alternativ kann 0xFFFF resultieren oder ein Interrupt wird ausgelöst oder ein spezielles Bit, das einen Überlauf anzeigt, wird an einem speziellen Ort gespeichert.

Solche Momente werden im Allgemeinen nirgendwo berücksichtigt, und die Regeln für die Verarbeitung solcher Operationen unterscheiden sich von Sprache zu Sprache. Wenn Gleitkomma-Kuriositäten zumindest durch den Standard festgelegt sind, ist die zuletzt aufgeworfene Frage im Prinzip unvorhersehbar.

Stattdessen würde ich für numerische Berechnungen vorschlagen, Datentypen mit einem definierbaren Wert mit einem festen Punkt und mit standardisiertem Verhalten einzuführen, falls die Genauigkeit verloren geht oder die obere oder untere Grenze überschritten wird. So etwas wie das:

1.000 / 3.000 = 0.333
0001 + 9999 = overflowed 9999
0.001 / 2 = underflowed 0


Es ist nicht erforderlich, alle nachgestellten Nullen anzuhängen: Ihr Vorhandensein muss durch die Definition des Datentyps impliziert werden. Es ist jedoch wichtig, die maximalen und minimalen Grenzen selbst auswählen zu können und nicht von der Prozessorarchitektur abhängig zu sein.

Funktionieren solche Berechnungen nicht langsamer? Ja, das werden sie. Aber fragen Sie sich: Wie oft müssen Sie Hochleistungsrechnen programmieren? Ich glaube, wenn Sie kein Experte auf diesem Gebiet sind, ist dies sehr selten. Und wenn Sie mit solchen Aufgaben beschäftigt sind, verwenden Sie für diese Zwecke spezielle Geräte und Compiler. Soweit ich das beurteilen kann, löst ein typischer Programmierer des 21. Jahrhunderts selten Differentialgleichungen.

Wie dem auch sei, nichts hindert die Verwendung schneller, komplexer und unvorhersehbarer integrierter Typen aus der Vergangenheit als Alternative und nicht als Standardoption.

Nieder mit der Praxis der Metasprachen!


Es gibt wunderbare Sprachen, die nicht für die Ausführung von Aufgaben erfunden wurden, sondern für die Erstellung von Sprachen, die diese ausführen können. Racket, Rebol und Forth sind nur einige Beispiele. Ich mag sie alle, mit ihnen zu spielen ist pure Freude. Aber wie Sie wahrscheinlich vermutet haben, ist die Freude an der Arbeit mit der Sprache nicht das Hauptkriterium, das die Sprache universell und beliebt macht.

Die Fähigkeit, neue Sprachen in einer Sprache zu erstellen, um eine bestimmte Aufgabe auszuführen, ist ein sehr leistungsfähiges Werkzeug, das sich bei unabhängigen Forschungsarbeiten voll auszahlt. Wenn der Code nicht nur für den Autor, sondern auch für den Hauptcode klar sein soll, müssen Sie leider andere Personen und die neue interne Sprache unterrichten. Und hier beginnen die Probleme.

Die Leute wollen die Aufgabe erledigen und keine Sprache lernen, die ihnen hilft, die Arbeit genau einmal zu erledigen, und danach werden sie sich nicht als nützlich erweisen. Für Außenstehende ist die Idee, Ihre Sprache zu beherrschen, eine Investition, die sich wahrscheinlich nicht auszahlt. Aber etwas Standardisiertes zu lernen ist eine Investition fürs Leben. Daher schreiben sie Ihren Code erneut und lernen ihn erst dann. Somit erscheinen unzählige Dialekte für eine angewandte Sphäre. Die Leute streiten sich über Ästhetik, Ideologie, Architektur und andere unwichtige Dinge. Und Millionen von Codezeilen werden geschrieben, um in wenigen Monaten in Vergessenheit zu geraten.

Die Lisp-Jungs haben das in den 80ern durchgemacht. Sie erkannten, dass je mehr angewandte Sprachelemente standardisiert sind, desto besser. So entstand Common Lisp.

Und er war riesig. Der INCITS 226–1994-Standard umfasst 1.153 Seiten. Dieser Rekord 17 Jahre später wurde nur von C ++ mit der Norm ISO / IEC 14882: 2011 (1338 Seiten) gebrochen. C ++ muss ein unerträgliches Erbe schleppen, obwohl es nicht immer so groß war. Common Lisp wurde größtenteils von Grund auf neu erstellt.

Die Programmiersprache sollte nicht so groß sein. Dies ist nicht erforderlich. Er braucht nur eine gute Standardbibliothek, die mit allen möglichen nützlichen Dingen gefüllt ist, damit die Leute das Rad nicht neu erfinden müssen.

Natürlich ist es nicht einfach, ein Gleichgewicht zwischen Größe und Anwendungseignung zu halten. Die Erfahrung von C ++ in der Praxis hat gezeigt, wie schwierig es ist. Ich glaube, um das notwendige Gleichgewicht zu erreichen, sollte die Sprache des 21. Jahrhunderts unter einem bestimmten Anwendungsbereich unter bestimmten Bedingungen geschärft werden. Da die meisten Probleme jetzt genau im Bereich der Geschäftsanwendungen auftreten, sollte sich die Sprache wahrscheinlich auf geschäftliche Probleme konzentrieren und nicht auf die Spieleentwicklung oder das Webdesign.

Also ...


Die Sprache des 21. Jahrhunderts sollte geschäftsorientiert sein, klare Sprachausdrücke verwenden und nicht von integrierten Typen abhängen. Schön, dass es eine solche Sprache schon gibt! Was denkst du, wovon reden wir?

Ja, das ist COBOL.

Dies ist eine der ersten Hochsprachen, die heute meist vergessen sind. Ich muss zugeben, dass ich die alten Merkmale von COBOL absichtlich als hochmodern und unglaublich vielversprechend beschrieben habe. Und ich habe es getan, um eines zu zeigen. Der Code wird nicht durch Sprachfunktionen geschrieben. Du machst es.

Es ist naiv zu glauben, dass die Sprache für die Qualität des Codes verantwortlich ist und dass das Hinzufügen (oder Entfernen) einiger Gadgets automatisch alles verbessern kann. Früher mochten Programmierer Fortran und COBOL nicht, deshalb erfanden sie C ++ und Java, um schließlich zu einer Situation zu gelangen, in der sie 20 oder 30 Jahre später auch alle nicht mochten.

Nach meinen Gefühlen liegt die Wurzel des Problems irgendwo im Bereich der Soziologie und Psychologie, aber nicht der Programmierung. Mögen wir Sprachen wirklich nicht so sehr? Und sind wir zufrieden mit dem Umfeld, in dem wir arbeiten? Windows ist anfällig, Visual Studio ist zu langsam, es ist unmöglich, Vim zu beenden. Tatsächlich sind es diese Dinge, die Unzufriedenheit verursachen, und nicht der kreative Prozess selbst.

Aber man muss immer den Schuldigen finden. Als Software-Ingenieure, die teilweise dafür verantwortlich sind, wie mies Programme sind, werden wir uns keine Vorwürfe machen, oder? Deshalb suchen wir nach Fehlern in den Werkzeugen. Lassen Sie uns neue COBOLs erfinden, bis eines Tages die Sonne heller scheint, die Vögel nicht lauter singen und Windows in 2 Sekunden geladen wird.

Aber höchstwahrscheinlich wird dieser Tag niemals kommen.

Wenn ich also die Programmiersprache des 21. Jahrhunderts erfinden wollte, würde ich stattdessen versuchen, einen neuen Ansatz für Verantwortung zu finden. Oder eine neue Möglichkeit, vorhandene Tools besser zu beherrschen. Ich würde versuchen, auf die wesentlichen Details zu achten und unnötige Komplexität gnadenlos loszuwerden. Anstelle von Sprachen, die in die Mode kommen und aus der Mode kommen, gibt es immer einige grundlegende Dinge, die ein ständiges Umdenken verdienen.

Bild

Source: https://habr.com/ru/post/de431558/


All Articles