Loading...

DIE HUNDERTJÄHRIGE SPRACHE

Original

April 2003

(Dieser Essay basiert auf einem Vortrag auf der PyCon 2003.)

Es ist schwer vorherzusagen, wie das Leben in hundert Jahren aussehen wird. Es gibt nur wenige Dinge, die wir mit Sicherheit sagen können. Wir wissen, dass jeder fliegende Autos fahren wird, dass die Bauvorschriften gelockert werden, um Gebäude mit Hunderten von Stockwerken zu ermöglichen, dass es die meiste Zeit dunkel sein wird und dass alle Frauen in der Kampfkunst ausgebildet sein werden. Hier möchte ich auf ein Detail dieses Bildes zoomen. Welche Programmiersprache werden sie verwenden, um die Software zu schreiben, die diese fliegenden Autos steuert?

Das ist es wert, darüber nachzudenken, nicht so sehr, weil wir diese Sprachen tatsächlich verwenden werden, sondern weil wir, wenn wir Glück haben, Sprachen auf dem Weg von diesem Punkt zu diesem Punkt verwenden werden.

Ich denke, dass Sprachen, wie Arten, evolutionäre Bäume bilden werden, mit Sackgassen, die überall abzweigen. Wir können das bereits beobachten. Cobol, trotz seiner zeitweiligen Popularität, scheint keine intellektuellen Nachkommen zu haben. Es ist eine evolutionäre Sackgasse - eine Neandertaler-Sprache.

Ich sage Java ein ähnliches Schicksal voraus. Die Leute schicken mir manchmal E-Mails mit der Aussage: "Wie kannst du sagen, dass Java keine erfolgreiche Sprache werden wird? Es ist bereits eine erfolgreiche Sprache." Und ich gebe zu, dass es das ist, wenn man Erfolg an dem Regalplatz misst, den Bücher darüber einnehmen (insbesondere einzelne Bücher darüber), oder an der Anzahl der Studenten, die glauben, dass sie es lernen müssen, um einen Job zu bekommen. Wenn ich sage, dass Java keine erfolgreiche Sprache werden wird, meine ich etwas Spezifischeres: dass Java sich als evolutionäre Sackgasse herausstellen wird, wie Cobol.

Das ist nur eine Vermutung. Ich könnte falsch liegen. Mein Punkt hier ist nicht, Java zu diskreditieren, sondern das Thema der evolutionären Bäume anzusprechen und die Leute dazu zu bringen, sich zu fragen, wo sich Sprache X auf dem Baum befindet? Der Grund, diese Frage zu stellen, ist nicht nur, damit unsere Geister in hundert Jahren sagen können: "Ich habe es dir ja gesagt." Es ist, weil es ein nützliches Heuristik ist, Sprachen zu finden, die jetzt gut zum Programmieren sind, wenn man sich an den Hauptzweigen hält.

Zu jeder Zeit sind Sie wahrscheinlich am glücklichsten auf den Hauptzweigen eines evolutionären Baumes. Selbst als es noch viele Neandertaler gab, muss es beschissen gewesen sein, einer zu sein. Die Cro-Magnoner wären ständig vorbeigekommen und hätten dich verprügelt und dir dein Essen gestohlen.

Der Grund, warum ich wissen möchte, wie Sprachen in hundert Jahren aussehen werden, ist, dass ich weiß, auf welchen Zweig des Baumes ich mich jetzt setzen soll.

Die Entwicklung von Sprachen unterscheidet sich von der Entwicklung von Arten, weil sich Zweige konvergieren können. Der Fortran-Zweig zum Beispiel scheint mit den Nachkommen von Algol zu verschmelzen. Theoretisch ist dies auch für Arten möglich, aber es ist nicht wahrscheinlich, dass es bei etwas Größerem als einer Zelle passiert ist.

Konvergenz ist bei Sprachen wahrscheinlicher, zum Teil, weil der Raum der Möglichkeiten kleiner ist, und zum Teil, weil Mutationen nicht zufällig sind. Sprachdesigner integrieren bewusst Ideen aus anderen Sprachen.

Es ist besonders nützlich für Sprachdesigner, darüber nachzudenken, wohin die Entwicklung von Programmiersprachen wahrscheinlich führen wird, weil sie entsprechend lenken können. In diesem Fall wird "auf einem Hauptzweig bleiben" mehr als ein Weg, um eine gute Sprache zu wählen. Es wird zu einem Heuristik, um die richtigen Entscheidungen über Sprachdesign zu treffen.

Jede Programmiersprache kann in zwei Teile geteilt werden: eine Reihe von grundlegenden Operatoren, die die Rolle von Axiomen spielen, und der Rest der Sprache, der im Prinzip in Bezug auf diese grundlegenden Operatoren geschrieben werden könnte.

Ich denke, dass die grundlegenden Operatoren der wichtigste Faktor für das langfristige Überleben einer Sprache sind. Den Rest können Sie ändern. Es ist wie die Regel, dass man beim Kauf eines Hauses zuerst die Lage berücksichtigen sollte. Alles andere kann man später reparieren, aber die Lage kann man nicht reparieren.

Ich denke, es ist wichtig, nicht nur, dass die Axiome gut gewählt sind, sondern auch, dass es nur wenige von ihnen gibt. Mathematiker haben schon immer so über Axiome gedacht - je weniger, desto besser - und ich denke, sie haben etwas erkannt.

Zumindest muss es eine nützliche Übung sein, sich den Kern einer Sprache genau anzusehen, um zu sehen, ob es Axiome gibt, die ausgesondert werden könnten. Ich habe in meiner langen Karriere als Schlamper festgestellt, dass Schrott Schrott erzeugt, und ich habe das sowohl in Software als auch unter Betten und in den Ecken von Räumen beobachtet.

Ich habe eine Ahnung, dass die Hauptzweige des evolutionären Baumes durch die Sprachen führen, die die kleinsten, saubersten Kerne haben. Je mehr von einer Sprache Sie in sich selbst schreiben können, desto besser.

Natürlich gehe ich von einer großen Annahme aus, wenn ich überhaupt frage, wie Programmiersprachen in hundert Jahren aussehen werden. Werden wir in hundert Jahren überhaupt noch Programme schreiben? Werden wir Computern nicht einfach sagen, was wir von ihnen wollen?

In dieser Hinsicht hat es bisher nicht viel Fortschritt gegeben. Ich vermute, dass die Menschen in hundert Jahren Computern immer noch sagen werden, was sie tun sollen, mit Programmen, die wir als solche erkennen würden. Es mag Aufgaben geben, die wir jetzt durch das Schreiben von Programmen lösen und die in hundert Jahren nicht mehr durch das Schreiben von Programmen gelöst werden müssen, aber ich denke, dass es immer noch eine Menge Programmierung der Art geben wird, die wir heute betreiben.

Es mag vermessen erscheinen, zu denken, dass jemand vorhersagen kann, wie eine Technologie in hundert Jahren aussehen wird. Aber denken Sie daran, dass wir bereits fast fünfzig Jahre Geschichte hinter uns haben. Hundert Jahre in die Zukunft zu schauen, ist eine greifbare Vorstellung, wenn man bedenkt, wie langsam sich Sprachen in den letzten fünfzig Jahren entwickelt haben.

Sprachen entwickeln sich langsam, weil sie nicht wirklich Technologien sind. Sprachen sind Notation. Ein Programm ist eine formale Beschreibung von dem Problem, das Sie von einem Computer für Sie lösen lassen wollen. Daher ist die Entwicklungsgeschwindigkeit von Programmiersprachen eher mit der Entwicklungsgeschwindigkeit von mathematischen Notationen vergleichbar als mit, sagen wir, Transport oder Kommunikation. Mathematische Notation entwickelt sich zwar, aber nicht mit den riesigen Sprüngen, die man in der Technologie sieht.

Woraus auch immer Computer in hundert Jahren bestehen, es scheint sicher zu sein, dass sie viel schneller sein werden als heute. Wenn Moores Gesetz weiter gilt, werden sie 74 Quintillionen (73.786.976.294.838.206.464) Mal schneller sein. Das ist irgendwie schwer vorstellbar. Und tatsächlich ist die wahrscheinlichste Vorhersage in der Geschwindigkeitsabteilung, dass Moores Gesetz aufhören wird zu funktionieren. Alles, was sich alle achtzehn Monate verdoppeln soll, scheint wahrscheinlich irgendwann an eine Art grundlegende Grenze zu stoßen. Aber ich habe keine Probleme damit zu glauben, dass Computer viel schneller sein werden. Selbst wenn sie nur ein bescheidenes Millionenmal schneller werden, sollte das die Spielregeln für die Programmierung von Sprachen erheblich verändern. Unter anderem wird es mehr Platz für das geben, was heute als langsame Sprachen betrachtet werden würde, d. h. Sprachen, die keinen sehr effizienten Code erzeugen.

Und doch werden einige Anwendungen immer noch Geschwindigkeit erfordern. Einige der Probleme, die wir mit Computern lösen wollen, werden von Computern selbst geschaffen; zum Beispiel hängt die Geschwindigkeit, mit der Sie Video-Bilder verarbeiten müssen, von der Geschwindigkeit ab, mit der ein anderer Computer sie generieren kann. Und es gibt eine weitere Klasse von Problemen, die von Natur aus eine unbegrenzte Fähigkeit haben, Zyklen aufzusaugen: Bildrendering, Kryptographie, Simulationen.

Wenn einige Anwendungen immer ineffizienter werden können, während andere weiterhin die gesamte Geschwindigkeit fordern, die die Hardware liefern kann, werden schnellere Computer bedeuten, dass Sprachen einen immer größeren Bereich von Effizienzen abdecken müssen. Wir haben das bereits beobachten können. Aktuelle Implementierungen einiger beliebter neuer Sprachen sind nach den Standards der vergangenen Jahrzehnte schockierend verschwenderisch.

Das ist nicht nur etwas, das mit Programmierung von Sprachen passiert. Es ist ein allgemeiner historischer Trend. Wenn sich Technologien verbessern, kann jede Generation Dinge tun, die die vorherige Generation als verschwenderisch betrachtet hätte. Menschen vor dreißig Jahren würden sich darüber wundern, wie beiläufig wir heute Telefonate über lange Strecken führen. Menschen vor hundert Jahren wären noch mehr erstaunt, dass ein Paket eines Tages von Boston nach New York über Memphis reisen würde.

Ich kann Ihnen jetzt schon sagen, was mit all den zusätzlichen Zyklen passieren wird, die uns die schnellere Hardware in den nächsten hundert Jahren liefern wird. Sie werden fast alle verschwendet werden.

Ich habe das Programmieren gelernt, als die Rechenleistung knapp war. Ich kann mich erinnern, dass ich alle Leerzeichen aus meinen Basic-Programmen entfernt habe, damit sie in den Speicher eines 4K TRS-80 passten. Der Gedanke an all diese stupide ineffiziente Software, die Zyklen verschwendet, indem sie immer wieder dasselbe tut, erscheint mir irgendwie eklig. Aber ich denke, meine Intuitionen hier sind falsch. Ich bin wie jemand, der arm aufgewachsen ist und kein Geld ausgeben kann, selbst für etwas Wichtiges, wie zum Beispiel einen Arztbesuch.

Manche Arten von Verschwendung sind wirklich ekelhaft. SUVs zum Beispiel wären argumentiert man, ekelhaft, selbst wenn sie mit einem Treibstoff betrieben würden, der niemals ausgehen würde und keine Umweltverschmutzung erzeugen würde. SUVs sind ekelhaft, weil sie die Lösung für ein ekelhaftes Problem sind. (Wie man Minivans männlicher aussehen lässt.) Aber nicht alle Verschwendung ist schlecht. Jetzt, wo wir die Infrastruktur haben, um sie zu unterstützen, beginnt es kleinlich zu erscheinen, die Minuten Ihrer Ferntelefonate zu zählen. Wenn Sie die Ressourcen haben, ist es eleganter, sich alle Telefonate als eine Art von Sache vorzustellen, egal wo sich die andere Person befindet.

Es gibt gute Verschwendung und schlechte Verschwendung. Ich interessiere mich für gute Verschwendung - die Art, bei der wir durch mehr Ausgaben einfachere Designs erhalten können. Wie werden wir die Möglichkeiten nutzen, Zyklen zu verschwenden, die wir durch neue, schnellere Hardware erhalten werden?

Der Wunsch nach Geschwindigkeit ist so tief in uns verwurzelt, mit unseren winzigen Computern, dass es einer bewussten Anstrengung bedarf, ihn zu überwinden. Im Sprachdesign sollten wir bewusst nach Situationen suchen, in denen wir Effizienz gegen selbst die kleinste Steigerung der Bequemlichkeit eintauschen können.

Die meisten Datenstrukturen existieren wegen der Geschwindigkeit. Zum Beispiel haben viele Sprachen heute sowohl Strings als auch Listen. Semantisch sind Strings mehr oder weniger eine Teilmenge von Listen, in denen die Elemente Zeichen sind. Warum brauchen Sie also einen separaten Datentyp? Das tun Sie eigentlich nicht. Strings existieren nur wegen der Effizienz. Aber es ist lahm, die Semantik der Sprache mit Hacks zu verunreinigen, um Programme schneller laufen zu lassen. Strings in einer Sprache zu haben, scheint ein Fall von vorzeitiger Optimierung zu sein.

Wenn wir den Kern einer Sprache als eine Menge von Axiomen betrachten, ist es sicher ekelhaft, zusätzliche Axiome zu haben, die keine zusätzliche Ausdruckskraft bringen, nur um der Effizienz willen. Effizienz ist wichtig, aber ich glaube nicht, dass das der richtige Weg ist, sie zu erreichen.

Der richtige Weg, dieses Problem zu lösen, ist meiner Meinung nach, die Bedeutung eines Programms von den Implementierungsdetails zu trennen. Anstatt sowohl Listen als auch Strings zu haben, haben Sie einfach Listen, mit einer Möglichkeit, dem Compiler Optimierungsratschläge zu geben, die es ihm ermöglichen, Strings als zusammenhängende Bytes zu verteilen, wenn erforderlich.

Da Geschwindigkeit in den meisten Teilen eines Programms keine Rolle spielt, werden Sie normalerweise nicht mit dieser Art von Mikromanagement belästigt werden müssen. Dies wird umso mehr zutreffen, je schneller Computer werden.

Weniger über die Implementierung zu sagen, sollte Programme auch flexibler machen. Spezifikationen ändern sich, während ein Programm geschrieben wird, und das ist nicht nur unvermeidlich, sondern auch wünschenswert.

Das Wort "Essay" kommt vom französischen Verb "essayer", das "versuchen" bedeutet. Ein Essay ist im ursprünglichen Sinne etwas, das man schreibt, um zu versuchen, etwas herauszufinden. Das passiert auch in Software. Ich denke, einige der besten Programme waren Essays, in dem Sinne, dass die Autoren nicht wussten, als sie anfingen, genau, was sie zu schreiben versuchten.

Lisp-Hacker wissen bereits über den Wert von Flexibilität mit Datenstrukturen Bescheid. Wir neigen dazu, die erste Version von einem Programm so zu schreiben, dass es alles mit Listen macht. Diese ersten Versionen können so schockierend ineffizient sein, dass es einer bewussten Anstrengung bedarf, nicht darüber nachzudenken, was sie tun, genau wie, zumindest für mich, das Essen eines Steaks einer bewussten Anstrengung bedarf, nicht darüber nachzudenken, woher es kommt.

Was Programmierer in hundert Jahren am meisten suchen werden, ist eine Sprache, in der man mit möglichst geringem Aufwand eine unglaublich ineffiziente Version 1 eines Programms zusammenstellen kann. Zumindest würden wir es in der heutigen Zeit so beschreiben. Was sie sagen werden, ist, dass sie eine Sprache wollen, die leicht zu programmieren ist.

Ineffiziente Software ist nicht ekelhaft. Was ekelhaft ist, ist eine Sprache, die Programmierer unnötige Arbeit verrichten lässt. Programmiererzeit zu verschwenden ist die wahre Ineffizienz, nicht Maschinenzeit zu verschwenden. Das wird immer deutlicher werden, je schneller Computer werden.

Ich denke, dass es bereits etwas ist, worüber wir nachdenken könnten, Strings loszuwerden. Wir haben es in Arc getan, und es scheint ein Gewinn zu sein; einige Operationen, die sich als reguläre Ausdrücke schwierig beschreiben lassen, lassen sich leicht als rekursive Funktionen beschreiben.

Wie weit wird diese Abflachung von Datenstrukturen gehen? Ich kann mir Möglichkeiten vorstellen, die selbst mich schockieren, mit meinem bewusst erweiterten Geist. Werden wir zum Beispiel Arrays loswerden? Schließlich sind sie nur eine Teilmenge von Hash-Tabellen, bei denen die Schlüssel Vektoren von Ganzzahlen sind. Werden wir Hash-Tabellen selbst durch Listen ersetzen?

Es gibt noch schockierendere Aussichten als das. Der Lisp, den McCarthy 1960 beschrieb, hatte zum Beispiel keine Zahlen. Logischerweise müssen Sie keine separate Vorstellung von Zahlen haben, weil Sie sie als Listen darstellen können: Die Ganzzahl n könnte als eine Liste von n Elementen dargestellt werden. Sie können auf diese Weise rechnen. Es ist nur unerträglich ineffizient.

Niemand hat tatsächlich vorgeschlagen, Zahlen in der Praxis als Listen zu implementieren. Tatsächlich war McCarthys 1960er Papier zu dieser Zeit nicht dazu gedacht, überhaupt implementiert zu werden. Es war eine theoretische Übung, ein Versuch, eine elegantere Alternative zur Turing-Maschine zu schaffen. Als jemand dann unerwartet dieses Papier nahm und es in einen funktionierenden Lisp-Interpreter übersetzte, wurden Zahlen sicherlich nicht als Listen dargestellt; sie wurden in binärer Form dargestellt, wie in jeder anderen Sprache.

Könnte eine Programmiersprache so weit gehen, Zahlen als grundlegenden Datentyp zu entfernen? Ich stelle diese Frage nicht so sehr als ernsthafte Frage, sondern als eine Möglichkeit, mit der Zukunft zu spielen. Es ist wie der hypothetische Fall einer unwiderstehlichen Kraft, die auf ein unbewegliches Objekt trifft - hier eine unvorstellbar ineffiziente Implementierung, die auf unvorstellbar große Ressourcen trifft. Ich sehe keinen Grund, warum nicht. Die Zukunft ist ziemlich lang. Wenn es etwas gibt, das wir tun können, um die Anzahl der Axiome im Kern der Sprache zu verringern, dann scheint das die Seite zu sein, auf die man setzen sollte, wenn t gegen Unendlich geht. Wenn die Idee in hundert Jahren immer noch unerträglich erscheint, vielleicht nicht mehr in tausend Jahren.

Um das klarzustellen, ich schlage nicht vor, dass alle numerischen Berechnungen tatsächlich mit Listen durchgeführt werden würden. Ich schlage vor, dass die Kernsprache, vor allen zusätzlichen Notationen über die Implementierung, auf diese Weise definiert wird. In der Praxis würde jedes Programm, das eine beliebige Menge an Mathematik durchführen möchte, wahrscheinlich Zahlen in binärer Form darstellen, aber dies wäre eine Optimierung, kein Teil der Semantik der Kernsprache.

Eine weitere Möglichkeit, Zyklen zu verbrennen, ist es, viele Schichten von Software zwischen der Anwendung und der Hardware zu haben. Auch das ist ein Trend, den wir bereits beobachten können: Viele neuere Sprachen werden in Bytecode kompiliert. Bill Woods hat mir einmal gesagt, dass, als Faustregel, jede Interpretationsschicht einen Faktor von 10 in der Geschwindigkeit kostet. Diese zusätzlichen Kosten kaufen Ihnen Flexibilität.

Die allererste Version von Arc war ein extremer Fall dieser Art von mehrstufiger Langsamkeit, mit entsprechenden Vorteilen. Es war ein klassischer "metazirkulärer" Interpreter, der auf Common Lisp geschrieben wurde, mit einer deutlichen Familienähnlichkeit zur eval-Funktion, die in McCarthys ursprünglichem Lisp-Papier definiert wurde. Das Ganze war nur ein paar hundert Zeilen Code, daher war es sehr einfach zu verstehen und zu ändern. Die Common Lisp, die wir verwendet haben, CLisp, läuft selbst auf einem Bytecode-Interpreter. Hier hatten wir also zwei Ebenen der Interpretation, eine davon (die oberste) schockierend ineffizient, und die Sprache war verwendbar. Kaum verwendbar, gebe ich zu, aber verwendbar.

Software als mehrere Schichten zu schreiben, ist eine leistungsstarke Technik auch innerhalb von Anwendungen. Bottom-up-Programmierung bedeutet, ein Programm als eine Reihe von Schichten zu schreiben, von denen jede als Sprache für die darüber liegende dient. Dieser Ansatz führt in der Regel zu kleineren, flexibleren Programmen. Es ist auch der beste Weg zu diesem heiligen Gral, der Wiederverwendbarkeit. Eine Sprache ist per Definition wiederverwendbar. Je mehr von Ihrer Anwendung Sie in eine Sprache zum Schreiben dieser Art von Anwendung verschieben können, desto mehr von Ihrer Software wird wiederverwendbar sein.

Irgendwie wurde die Idee der Wiederverwendbarkeit in den 1980er Jahren mit der objektorientierten Programmierung verbunden, und keine Menge an Beweisen für das Gegenteil scheint sie davon lösen zu können. Aber obwohl einige objektorientierte Software wiederverwendbar ist, ist das, was sie wiederverwendbar macht, ihre Bottom-up-Natur, nicht ihre Objektorientierung. Betrachten Sie Bibliotheken: Sie sind wiederverwendbar, weil sie Sprache sind, ob sie nun in einem objektorientierten Stil geschrieben sind oder nicht.

Ich sage übrigens nicht die Abschaffung der objektorientierten Programmierung voraus. Obwohl ich nicht glaube, dass sie guten Programmierern viel zu bieten hat, außer in bestimmten spezialisierten Bereichen, ist sie für große Organisationen unwiderstehlich. Objektorientierte Programmierung bietet eine nachhaltige Möglichkeit, Spaghetti-Code zu schreiben. Sie ermöglicht es Ihnen, Programme als eine Reihe von Patches zu akkumulieren.

Große Organisationen entwickeln Software immer auf diese Weise, und ich erwarte, dass dies in hundert Jahren genauso zutreffen wird wie heute.

Solange wir über die Zukunft sprechen, sollten wir auch über parallele Berechnung sprechen, denn dort scheint diese Idee zu leben. Das heißt, egal wann Sie darüber sprechen, parallele Berechnung scheint etwas zu sein, das in der Zukunft passieren wird.

Wird die Zukunft jemals damit Schritt halten? Die Leute sprechen schon seit mindestens 20 Jahren über parallele Berechnung als etwas unmittelbar Bevorstehendes, und sie hat die Programmierpraxis bisher nicht viel beeinflusst. Oder doch? Bereits Chip-Designer müssen darüber nachdenken, und das müssen auch die Leute, die versuchen, Systemsoftware auf Multi-CPU-Computern zu schreiben.

Die eigentliche Frage ist, wie weit die Abstraktionsebene der Parallelität reichen wird? Wird sie in hundert Jahren auch Anwendungsprogrammierer betreffen? Oder wird es etwas sein, worüber Compiler-Schreiber nachdenken, aber das im Quellcode von Anwendungen normalerweise unsichtbar ist?

Eine Sache, die wahrscheinlich ist, ist, dass die meisten Möglichkeiten für Parallelität verschwendet werden. Dies ist ein Sonderfall meiner allgemeineren Vorhersage, dass die meiste zusätzliche Rechenleistung, die uns gegeben wird, verschwendet werden wird. Ich erwarte, dass, wie bei der enormen Geschwindigkeit der zugrunde liegenden Hardware, Parallelität etwas sein wird, das verfügbar ist, wenn Sie explizit danach fragen, aber normalerweise nicht verwendet wird. Dies impliziert, dass die Art von Parallelität, die wir in hundert Jahren haben werden, nicht, außer in speziellen Anwendungen, massive Parallelität sein wird. Ich erwarte, dass es für gewöhnliche Programmierer eher so sein wird, als ob man Prozesse abzweigen könnte, die alle parallel laufen.

Und das wird, wie das Anfordern spezifischer Implementierungen von Daten strukturen, etwas sein, das Sie ziemlich spät im Leben eines Programms tun, wenn Sie versuchen, es zu optimieren. Version 1s werden normalerweise alle Vorteile ignorieren, die sich aus der parallelen Berechnung ergeben, genau wie sie die Vorteile ignorieren, die sich aus spezifischen Darstellungen von Daten ergeben.

Außer in speziellen Arten von Anwendungen wird Parallelität nicht die Programme durchdringen, die in hundert Jahren geschrieben werden. Es wäre eine vorzeitige Optimierung, wenn es so wäre.

Wie viele Programmiersprachen wird es in hundert Jahren geben? Es scheint in letzter Zeit eine riesige Anzahl neuer Programmiersprachen zu geben. Ein Teil des Grundes ist, dass schnellere Hardware es Programmierern ermöglicht hat, verschiedene Kompromisse zwischen Geschwindigkeit und Komfort einzugehen, abhängig von der Anwendung. Wenn dies ein echter Trend ist, sollte die Hardware, die wir in hundert Jahren haben werden, diesen Trend nur noch verstärken.

Und doch wird es in hundert Jahren vielleicht nur noch wenige weit verbreitete Sprachen geben. Ein Teil des Grundes, warum ich das sage, ist Optimismus: Es scheint, dass man, wenn man wirklich gute Arbeit leisten würde, eine Sprache schaffen könnte, die ideal zum Schreiben einer langsamen Version 1 geeignet ist, und die mit den richtigen Optimierungsratschlägen an den Compiler auch sehr schnellen Code erzeugen würde, wenn nötig. Da ich also optimistisch bin, werde ich vorhersagen, dass trotz der riesigen Lücke, die sie zwischen akzeptabler und maximaler Effizienz haben werden, Programmierer in hundert Jahren Sprachen haben werden, die den größten Teil davon abdecken können.

Wenn sich diese Lücke erweitert, werden Profiler immer wichtiger. Profiler werden heute kaum beachtet. Viele Leute scheinen immer noch zu glauben, dass der Weg zu schnellen Anwendungen darin besteht, Compiler zu schreiben, die schnellen Code erzeugen. Wenn sich die Lücke zwischen akzeptabler und maximaler Leistung erweitert, wird es immer deutlicher werden, dass der Weg zu schnellen Anwendungen darin besteht, einen guten Leitfaden von einem zum anderen zu haben.

Wenn ich sage, dass es vielleicht nur noch wenige Sprachen geben wird, dann schließe ich domänenspezifische "kleine Sprachen" nicht ein. Ich denke, solche eingebetteten Sprachen sind eine großartige Idee, und ich erwarte, dass sie sich vermehren werden. Aber ich erwarte, dass sie als dünne genug Hüllen geschrieben werden, so dass Benutzer die allgemeine Sprache darunter sehen können.

Wer wird die Sprachen der Zukunft entwerfen? Einer der spannendsten Trends der letzten zehn Jahre war der Aufstieg von Open-Source- Sprachen wie Perl, Python und Ruby. Sprachdesign wird von Hackern übernommen. Die Ergebnisse sind bisher chaotisch, aber ermutigend. Es gibt einige erstaunlich neuartige Ideen in Perl, zum Beispiel. Viele sind erstaunlich schlecht, aber das ist bei ambitionierten Bemühungen immer der Fall. Bei seiner derzeitigen Mutationsrate weiß Gott, wozu sich Perl in hundert Jahren entwickeln könnte.

Es stimmt nicht, dass diejenigen, die nicht können, lehren (einige der besten Hacker, die ich kenne, sind Professoren), aber es stimmt, dass es eine Menge Dinge gibt, die diejenigen, die lehren, nicht können. Forschung erlegt einschränkende Kastenbeschränkungen auf. In jedem akademischen Bereich gibt es Themen, an denen man arbeiten darf, und andere, an denen man nicht arbeiten darf. Leider basiert die Unterscheidung zwischen akzeptablen und verbotenen Themen in der Regel darauf, wie intellektuell die Arbeit klingt, wenn sie in Forschungsarbeiten beschrieben wird, anstatt wie wichtig sie für das Erreichen guter Ergebnisse ist. Der extreme Fall ist wahrscheinlich die Literatur; Menschen, die Literatur studieren, sagen selten etwas, das für diejenigen, die sie produzieren, von geringster Bedeutung wäre.

Obwohl die Situation in den Wissenschaften besser ist, ist die Überschneidung zwischen der Art von Arbeit, die man machen darf, und der Art von Arbeit, die gute Sprachen hervorbringt, erschreckend gering. (Olin Shivers hat sich eloquent darüber geäußert.) Zum Beispiel scheinen Typen eine unerschöpfliche Quelle von Forschungsarbeiten zu sein, obwohl statische Typisierung wahre Makros zu verhindern scheint - ohne die, meiner Meinung nach, keine Sprache es wert ist, verwendet zu werden.

Der Trend geht nicht nur dahin, dass Sprachen als Open-Source-Projekte entwickelt werden, anstatt als "Forschung", sondern auch dahin, dass Sprachen von den Anwendungsprogrammierern entworfen werden, die sie benötigen, anstatt von Compiler-Schreibern. Das scheint ein guter Trend zu sein, und ich erwarte, dass er sich fortsetzen wird.

Im Gegensatz zur Physik in hundert Jahren, die sich fast zwangsläufig unmöglich vorhersagen lässt, denke ich, dass es im Prinzip möglich sein könnte, jetzt eine Sprache zu entwerfen, die Benutzer in hundert Jahren ansprechen würde.

Eine Möglichkeit, eine Sprache zu entwerfen, ist, einfach das Programm aufzuschreiben, das Sie gerne schreiben würden, unabhängig davon, ob es einen Compiler gibt, der es übersetzen kann, oder Hardware, die es ausführen kann. Wenn Sie das tun, können Sie unbegrenzte Ressourcen annehmen. Es scheint, als sollten wir uns heute genauso gut unbegrenzte Ressourcen vorstellen können wie in hundert Jahren.

Welches Programm würde man gerne schreiben? Was am wenigsten Arbeit macht. Aber nicht ganz: Was wäre am wenigsten Arbeit, wenn Ihre Vorstellungen von Programmierung nicht schon von den Sprachen beeinflusst wären, die Sie derzeit verwenden. Solch ein Einfluss kann so allgegenwärtig sein, dass es einer großen Anstrengung bedarf, ihn zu überwinden. Man würde denken, es wäre für Kreaturen, die so faul sind wie wir, offensichtlich, wie man ein Programm mit dem geringsten Aufwand ausdrückt. Tatsächlich sind unsere Vorstellungen davon, was möglich ist, in der Regel so begrenzt durch die Sprache, in der wir denken, dass einfachere Formulierungen von Programmen sehr überraschend erscheinen. Sie sind etwas, das man entdecken muss, nicht etwas, in das man auf natürliche Weise hineinsinkt.

Ein hilfreicher Trick dabei ist es, die Länge des Programms als Näherung für den Arbeitsaufwand zu verwenden, der zum Schreiben erforderlich ist. Natürlich nicht die Länge in Zeichen, sondern die Länge in verschiedenen syntaktischen Elementen - im Wesentlichen die Größe des Parse-Baums. Es mag nicht ganz stimmen, dass das kürzeste Programm am wenigsten Arbeit zum Schreiben erfordert, aber es ist nahe genug, dass Sie besser dran sind, wenn Sie auf das solide Ziel der Kürze zielen, als auf das verschwommene, naheliegende Ziel des geringsten Arbeitsaufwands. Dann lautet der Algorithmus für Sprachdesign: Betrachten Sie ein Programm und fragen Sie sich: Gibt es eine Möglichkeit, dies kürzer zu schreiben?

In der Praxis wird das Schreiben von Programmen in einer imaginären hundertjährigen Sprache in unterschiedlichem Maße funktionieren, je nachdem, wie nah Sie am Kern sind. Sortier-Routinen können Sie jetzt schreiben. Aber es wäre schwer vorherzusagen, welche Arten von Bibliotheken in hundert Jahren benötigt werden könnten. Vermutlich werden viele Bibliotheken für Bereiche sein, die noch gar nicht existieren. Wenn SETI@home funktioniert, zum Beispiel, werden wir Bibliotheken für die Kommunikation mit Außerirdischen benötigen. Es sei denn natürlich, sie sind so weit fortgeschritten, dass sie bereits in XML kommunizieren.

Am anderen Ende des Spektrums denke ich, dass Sie die Kernsprache heute entwerfen könnten. Tatsächlich könnten einige argumentieren, dass sie bereits 1958 größtenteils entworfen wurde.

Wenn die hundertjährige Sprache heute verfügbar wäre, würden wir dann in ihr programmieren wollen? Eine Möglichkeit, diese Frage zu beantworten, ist, zurückzublicken. Wenn die heutigen Programmiersprachen 1960 verfügbar gewesen wären, hätte jemand sie verwenden wollen?

In gewisser Weise lautet die Antwort nein. Sprachen heute setzen Infrastruktur voraus, die 1960 nicht existierte. Zum Beispiel würde eine Sprache, in der Einrückungen von Bedeutung sind, wie Python, nicht sehr gut auf Druckern funktionieren. Aber wenn man solche Probleme beiseite lässt - angenommen, zum Beispiel, dass Programme alle nur auf Papier geschrieben wurden - hätten Programmierer der 1960er Jahre gerne Programme in den Sprachen geschrieben, die wir heute verwenden?

Ich denke schon. Einige der weniger einfallsreichen, die Artefakte früherer Sprachen in ihre Vorstellungen von einem Programm eingebaut hatten, hätten vielleicht Schwierigkeiten gehabt. (Wie kann man Daten manipulieren, ohne Pointer-Arithmetik zu betreiben? Wie kann man Flussdiagramme ohne Gotos implementieren?) Aber ich denke, die klügsten Programmierer hätten keine Probleme gehabt, das Beste aus den heutigen Sprachen zu machen, wenn sie sie gehabt hätten.

Wenn wir die hundertjährige Sprache jetzt hätten, wäre sie zumindest ein toller Pseudocode. Was ist mit der Verwendung zum Schreiben von Software? Da die hundertjährige Sprache schnellen Code für einige Anwendungen generieren muss, könnte sie vermutlich Code generieren, der effizient genug ist, um auf unserer Hardware akzeptabel gut zu laufen. Wir müssten vielleicht mehr Optimierungsratschläge geben als Benutzer in hundert Jahren, aber es könnte trotzdem ein Gewinn sein.

Jetzt haben wir zwei Ideen, die, wenn man sie kombiniert, interessante Möglichkeiten eröffnen: (1) die hundertjährige Sprache könnte im Prinzip heute entworfen werden, und (2) eine solche Sprache, wenn sie existieren würde, könnte gut sein, um heute in ihr zu programmieren. Wenn man diese Ideen so dargelegt sieht, ist es schwer, nicht zu denken: Warum nicht versuchen, die hundertjährige Sprache jetzt zu schreiben?

Wenn Sie an Sprachdesign arbeiten, denke ich, ist es gut, ein solches Ziel zu haben und es bewusst im Auge zu behalten. Wenn Sie Autofahren lernen, ist eines der Prinzipien, die Ihnen beigebracht werden, das Auto nicht auszurichten, indem Sie die Motorhaube mit den Streifen ausrichten, die auf die Straße gemalt sind, sondern indem Sie auf einen Punkt in der Ferne zielen. Selbst wenn Sie sich nur um die nächsten zehn Fuß kümmern, ist dies die richtige Antwort. Ich denke, wir können und sollten dasselbe mit Programmiersprachen tun.

Hinweise

Ich glaube, Lisp Machine Lisp war die erste Sprache, die das Prinzip verkörperte, dass Deklarationen (außer denen von dynamischen Variablen) nur Optimierungsratschläge waren, und die Bedeutung eines korrekten Programms nicht ändern würden. Common Lisp scheint das als erster explizit zu erwähnen.

Danke an Trevor Blackwell, Robert Morris und Dan Giffin für das Lesen von Entwürfen dieses Textes und an Guido van Rossum, Jeremy Hylton und die anderen Mitglieder des Python-Teams für die Einladung, auf der PyCon zu sprechen.