Loading...

DIE HUNDERTJÄHRIGE SPRACHE

Original

April 2003

(Dieser Aufsatz ist von einer Keynote-Rede auf der PyCon 2003 abgeleitet.)

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 alle fliegende Autos fahren werden, dass Bebauungspläne gelockert werden, um Gebäude mit hunderten von Stockwerken zu erlauben, dass es die meiste Zeit dunkel sein wird und dass alle Frauen in Kampfkünsten ausgebildet sein werden. Hier möchte ich mich auf ein Detail dieses Bildes konzentrieren. Welche Programmiersprache werden sie benutzen, 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 benutzen werden, sondern weil wir, wenn wir Glück haben, Sprachen auf dem Weg von diesem Punkt zu jenem benutzen werden.

Ich denke, dass Sprachen, wie Spezies, evolutionäre Bäume bilden werden, mit Sackgassen, die überall abzweigen. Wir können sehen, dass dies bereits geschieht. Cobol, so populär es auch manchmal war, scheint keine intellektuellen Nachkommen zu haben. Es ist eine evolutionäre Sackgasse - eine Neandertaler-Sprache.

Ich sage eine ähnliche Zukunft für Java voraus. Manchmal schicken mir Leute E-Mails und sagen: "Wie können Sie sagen, dass Java keine erfolgreiche Sprache sein wird? Es ist bereits eine erfolgreiche Sprache." Und ich gebe zu, dass es das ist, wenn man Erfolg an dem Platz in Regalen misst, den Bücher darüber einnehmen (insbesondere einzelne Bücher darüber), oder an der Zahl der Studenten, die glauben, sie müssten sie lernen, um einen Job zu bekommen. Wenn ich sage, dass Java keine erfolgreiche Sprache sein wird, meine ich etwas Spezifischeres: Dass Java sich als evolutionäre Sackgasse erweisen wird, wie Cobol.

Das ist nur eine Vermutung. Ich könnte falsch liegen. Mein Punkt hier ist nicht, Java schlecht zu machen, sondern das Thema der evolutionären Bäume aufzuwerfen und die Leute zu fragen, wo auf dem Baum Sprache X steht. Der Grund, diese Frage zu stellen, ist nicht nur, damit unsere Geister in hundert Jahren sagen können: "Ich habe es euch ja gesagt." Es ist, weil es ein nützlicher Heuristik ist, die Hauptäste zu finden, um Sprachen zu finden, die jetzt gut zum Programmieren geeignet sind.

Zu jeder gegebenen Zeit ist man wahrscheinlich am glücklichsten auf den Hauptästen eines evolutionären Baumes. Selbst als es noch reichlich Neandertaler gab, muss es Scheiße gewesen sein, einer zu sein. Die Cro-Magnon-Menschen werden ständig gekommen sein, um dich zu verprügeln und dir dein Essen zu stehlen.

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

Die Evolution von Sprachen unterscheidet sich von der Evolution von Spezies dadurch, dass Äste konvergieren können. Der Fortran-Ast scheint sich zum Beispiel mit den Nachkommen von Algol zu vermischen. Theoretisch ist das auch für Spezies möglich, aber es ist unwahrscheinlich, dass es größer als eine Zelle passiert ist.

Konvergenz ist für Sprachen wahrscheinlicher, zum Teil weil der Möglichkeitsraum kleiner ist, und zum Teil weil Mutationen nicht zufällig sind. Sprachdesigner übernehmen bewusst Ideen aus anderen Sprachen.

Es ist besonders nützlich für Sprachdesigner, darüber nachzudenken, wohin sich die Evolution von Programmiersprachen wahrscheinlich entwickeln wird, denn dann können sie entsprechend steuern. In diesem Fall wird "bleib auf einem Hauptast" mehr als nur eine Heuristik, um eine gute Sprache zu wählen. Es wird zu einer Heuristik, um die richtigen Entscheidungen über Sprachdesign zu treffen.

Jede Programmiersprache kann in zwei Teile unterteilt werden: eine Menge grundlegender Operatoren, die die Rolle von Axiomen spielen, und der Rest der Sprache, der prinzipiell 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 kann man ändern. Es ist wie die Regel, dass man beim Hausbau zuerst auf die Lage achten sollte. Alles andere kann man später reparieren, aber die Lage kann man nicht ändern.

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

Zumindest muss es eine nützliche Übung sein, den Kern einer Sprache genau anzuschauen, um zu sehen, ob es Axiome gibt, die man herausnehmen könnte. In meiner langen Karriere als Schluffi habe ich festgestellt, dass Krempel Krempel erzeugt, und ich habe das auch in Software gesehen, ebenso wie unter Betten und in Ecken.

Ich habe eine Ahnung, dass die Hauptäste des evolutionären Baumes durch die Sprachen führen, die den kleinsten, saubersten Kern haben. Je mehr von einer Sprache man in sich selbst schreiben kann, desto besser.

Natürlich mache ich eine große Annahme, indem ich überhaupt frage, wie Programmiersprachen in hundert Jahren aussehen werden. Werden wir in hundert Jahren überhaupt noch Programme schreiben? Werden wir den Computern einfach sagen, was wir wollen, dass sie tun sollen?

Es hat in dieser Hinsicht bisher nicht viel Fortschritt gegeben. Meine Vermutung ist, dass die Leute in hundert Jahren immer noch Computer mit Programmen anweisen werden, die wir als solche erkennen würden. Es mag Aufgaben geben, die wir heute durch Programmschreiben lösen und die in hundert Jahren nicht mehr programmiert werden müssen, aber ich denke, es wird immer noch eine gute Menge an Programmierung der Art, die wir heute machen, geben.

Es mag vermessen erscheinen, zu denken, dass irgendjemand 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 blicken, ist eine greifbare Idee, wenn man bedenkt, wie langsam sich Sprachen in den letzten fünfzig Jahren entwickelt haben.

Sprachen entwickeln sich langsam, weil sie keine wirklichen Technologien sind. Sprachen sind Notation. Ein Programm ist eine formale Beschreibung des Problems, das ein Computer für dich lösen soll. Daher ist die Evolutionsrate von Programmiersprachen eher mit der Evolutionsrate mathematischer Notation vergleichbar als mit der von Verkehr oder Kommunikation. Mathematische Notation entwickelt sich weiter, aber nicht mit den riesigen Sprüngen, die man bei Technologien sieht.

Was auch immer Computer in hundert Jahren aus Computern gemacht werden, es scheint sicher vorherzusagen, dass sie viel schneller sein werden als sie es jetzt sind. Wenn Moores Gesetz weiterhin Gültigkeit hat, werden sie 74 Quintillionen (73.786.976.294.838.206.464) Mal schneller sein. Das ist irgendwie schwer vorstellbar. Und in der Tat, die wahrscheinlichste Vorhersage im Bereich der Geschwindigkeit könnte sein, dass Moores Gesetz aufhört zu funktionieren. Alles, was alle achtzehn Monate verdoppeln soll, scheint irgendwann an eine Art fundamentale Grenze zu stoßen.

Aber ich habe keine Schwierigkeiten zu glauben, dass Computer sehr viel schneller sein werden. Selbst wenn sie am Ende nur eine lächerliche Million Mal schneller sind, sollte das die Spielregeln für Programmiersprachen erheblich verändern. Unter anderem wird es mehr Platz für das geben, was man jetzt als langsame Sprachen bezeichnen würde, was Sprachen bedeutet, die nicht sehr effiziente Codes liefern.

Und doch werden einige Anwendungen immer noch Geschwindigkeit verlangen. Einige der Probleme, die wir mit Computern lösen wollen, werden von Computern selbst geschaffen; zum Beispiel hängt die Geschwindigkeit, mit der man Videobilder verarbeiten muss, von der Geschwindigkeit ab, mit der ein anderer Computer sie erzeugen kann. Und es gibt eine andere Klasse von Problemen, die eine unbegrenzte Kapazität haben, Zyklen zu verschlingen: Bildwiedergabe, Kryptographie, Simulationen.

Wenn einige Anwendungen zunehmend ineffizient sein können, während andere weiterhin alle Geschwindigkeit verlangen, die die Hardware liefern kann, werden schnellere Computer bedeuten, dass Sprachen ein immer breiteres Spektrum an Effizienz abdecken müssen. Wir haben das schon gesehen. Aktuelle Implementierungen einiger beliebter neuer Sprachen sind schockierend verschwenderisch im Vergleich zu früheren Jahrzehnten.

Das ist nicht nur etwas, was mit Programmiersprachen passiert. Es ist ein allgemeiner historischer Trend. Mit der Verbesserung der Technologien kann jede Generation Dinge tun, die die vorherige Generation als verschwenderisch betrachtet hätte. Leute vor dreißig Jahren wären erstaunt darüber, wie selbstverständlich wir Ferngespräche führen. Leute 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 schon jetzt sagen, was mit all den zusätzlichen Zyklen passieren wird, die uns die schnellere Hardware in den nächsten hundert Jahren geben wird. Sie werden fast alle verschwendet werden.

Ich habe gelernt zu programmieren, als Rechenleistung knapp war. Ich kann mich erinnern, dass ich alle Leerzeichen aus meinen Basic-Programmen genommen habe, damit sie in den Speicher eines 4K TRS-80 passten. Der Gedanke an all diese unglaublich ineffiziente Software, die Zyklen verschwendet, indem sie immer wieder dasselbe tut, kommt mir irgendwie ekelhaft vor. Aber ich glaube, meine Intuitionen hier sind falsch. Ich bin wie jemand, der in Armut aufgewachsen ist und kein Geld ausgeben kann, auch nicht für etwas Wichtiges wie einen Arztbesuch.

Manche Arten von Verschwendung sind wirklich ekelhaft. SUVs zum Beispiel wären argumentativ ekelhaft, selbst wenn sie mit einem Kraftstoff fahren würden, der niemals ausgehen und keine Verschmutzung erzeugen würde. SUVs sind ekelhaft, weil sie die Lösung für ein ekelhaftes Problem sind. (Wie man Minivans maskuliner aussehen lässt.)

Aber nicht alle Verschwendung ist schlecht. Jetzt, da wir die Infrastruktur haben, um sie zu unterstützen, beginnt das Zählen der Minuten Ihrer Ferngespräche kleinlich zu erscheinen. Wenn man die Ressourcen hat, ist es eleganter, alle Telefongespräche als eine Art Ding zu betrachten, egal wo der andere ist.

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

Der Wunsch nach Geschwindigkeit ist so tief in uns verwurzelt, mit unseren lächerlichen Computern, dass es eine bewusste Anstrengung erfordern wird, ihn zu überwinden. Bei der Sprachgestaltung sollten wir bewusst nach Situationen suchen, in denen wir Effizienz gegen auch nur den kleinsten Zuwachs an Bequemlichkeit eintauschen können.

Die meisten Datenstrukturen existieren aufgrund von Geschwindigkeit. Zum Beispiel haben viele Sprachen heute sowohl Strings als auch Listen. Semantisch gesehen sind Strings mehr oder weniger eine Teilmenge von Listen, bei denen die Elemente Zeichen sind. Warum braucht man also einen separaten Datentyp? Eigentlich braucht man ihn nicht. Strings existieren nur aus Effizienzgründen. Aber es ist lächerlich, die Semantik der Sprache mit Hacks zu belasten, 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 Menge von Axiomen betrachten, ist es sicher ekelhaft, zusätzliche Axiome zu haben, die keine zusätzliche Ausdruckskraft hinzufügen, sondern nur der Effizienz dienen. 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 es, 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 Optimierungshinweise zu geben, die es ihm ermöglichen, Strings als zusammenhängende Bytes darzustellen, wenn nötig.

Da Geschwindigkeit in den meisten Teilen eines Programms keine Rolle spielt, werden Sie normalerweise keine Notwendigkeit haben, sich mit dieser Art von Mikromanagement zu befassen. Das wird immer mehr der Fall sein, je schneller die Computer werden.

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

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

Lisp-Hacker wissen schon um den Wert der Flexibilität bei Datenstrukturen. Wir neigen dazu, die erste Version eines Programms so zu schreiben, dass es alles mit Listen erledigt. Diese ersten Versionen können so schockierend ineffizient sein, dass es eine bewusste Anstrengung erfordert, nicht darüber nachzudenken, was sie tun, genauso wie es für mich zumindest eine bewusste Anstrengung erfordert, beim Essen eines Steaks nicht darüber nachzudenken, woher er kommt.

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

Ineffiziente Software ist nicht ekelhaft. Was ekelhaft ist, ist eine Sprache, die Programmierer zu unnötiger Arbeit zwingt. Die Verschwendung von Programmiererzeit ist die wahre Ineffizienz, nicht die Verschwendung von Maschinenzeit. Das wird immer deutlicher, je schneller die Computer werden.

Ich denke, dass es schon etwas ist, über das Beseitigen von Zeichenketten nachzudenken. Wir haben es in Arc getan, und es scheint ein Gewinn zu sein; einige Operationen, die als reguläre Ausdrücke unbeholfen zu beschreiben wären, lassen sich leicht als rekursive Funktionen beschreiben.

Wie weit wird diese Vereinfachung von Datenstrukturen gehen? Ich kann mir Möglichkeiten vorstellen, die mich selbst mit meinem gewissenhaft erweiterten Geist schockieren. Werden wir zum Beispiel Arrays beseitigen? Schließlich sind sie nur eine Teilmenge von Hashtabellen, bei denen die Schlüssel Vektoren von ganzen Zahlen sind. Werden wir Hashtabellen selbst durch Listen ersetzen?

Es gibt noch schockierendere Aussichten als das. Die Lisp, die McCarthy 1960 beschrieb, hatte zum Beispiel keine Zahlen. Logisch gesehen braucht man keinen separaten Zahlenbegriff, da man sie als Listen darstellen kann: Die ganze Zahl n könnte als eine Liste von n Elementen dargestellt werden. Man kann so Mathematik betreiben. Es ist nur unerträglich ineffizient.

Niemand hat tatsächlich vorgeschlagen, Zahlen in der Praxis als Listen zu implementieren. Tatsächlich war McCarthys Arbeit von 1960 zu diesem Zeitpunkt nicht als Implementierung gedacht. Es war eine theoretische Übung, der Versuch, eine elegantere Alternative zur Turingmaschine zu schaffen. Als jemand unerwartet dieses Papier nahm und es in einen funktionierenden Lisp-Interpreter übersetzte, wurden Zahlen sicher nicht als Listen dargestellt; sie wurden in Binärform dargestellt, wie in jeder anderen Sprache auch.

Könnte eine Programmiersprache so weit gehen, Zahlen als grundlegenden Datentyp zu beseitigen? Ich stelle diese Frage nicht so sehr als ernsthafte Frage, sondern eher als Weg, um die Zukunft herauszufordern. 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 Zahl der Axiome in der Kernsprache zu verringern, dann wäre das der Weg, auf den man setzen sollte, wenn sich t der Unendlichkeit nähert. Wenn die Idee in hundert Jahren immer noch unerträglich erscheint, vielleicht nicht mehr in tausend.

Um das klarzustellen: Ich schlage nicht vor, dass alle numerischen Berechnungen tatsächlich mit Listen durchgeführt werden. Ich schlage vor, dass die Kernsprache, bevor irgendwelche zusätzlichen Notationen zur Implementierung hinzukommen, so definiert wird. In der Praxis würde jedes Programm, das irgendeine Form von Mathematik durchführen möchte, Zahlen wahrscheinlich in Binärform darstellen, aber das wäre eine Optimierung, nicht Teil der Kernsprachensemantik.

Eine andere Möglichkeit, Zyklen zu verbrauchen, ist es, viele Softwareschichten zwischen der Anwendung und der Hardware zu haben. Dies ist ebenfalls ein Trend, den wir bereits sehen: Viele neuere Sprachen werden in Bytecode kompiliert. Bill Woods sagte mir einmal, dass als Daumenregel jede Interpretationsschicht einen Faktor von 10 in der Geschwindigkeit kostet. Diese zusätzlichen Kosten bringen 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 aufbaut und eine deutliche Familienähnlichkeit zur eval-Funktion hat, die in McCarthys ursprünglichem Lisp-Papier definiert ist. Das Ganze umfasste nur ein paar hundert Zeilen Code, so dass es sehr leicht zu verstehen und zu ändern war. Das von uns verwendete Common Lisp, CLisp, läuft selbst auf einem Bytecode-Interpreter. Hier hatten wir also zwei Interpretationsebenen, von denen eine (die oberste) schockierend ineffizient war, und die Sprache war dennoch verwendbar. Kaum verwendbar, gebe ich zu, aber verwendbar.

Die Entwicklung von Software in mehreren Schichten ist eine leistungsfähige 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überliegende dient. Dieser Ansatz führt tendenziell zu kleineren, flexibleren Programmen. Es ist auch der beste Weg zu jenem 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 verlagern können, desto mehr Ihrer Software wird wiederverwendbar sein.

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

Ich prognostiziere übrigens nicht den Untergang der objektorientierten Programmierung. Obwohl sie für gute Programmierer nicht viel zu bieten hat, außer in bestimmten spezialisierten Domänen, ist sie für große Organisationen unwiderstehlich. Objektorientierte Programmierung bietet einen nachhaltigen Weg, um Spaghetticode zu schreiben. Sie ermöglicht es Ihnen, Programme als eine Reihe von Patches zu akkumulieren.

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

Wenn wir schon über die Zukunft sprechen, müssen wir auch über die parallele Berechnung sprechen, denn dort scheint diese Idee zu leben. Das heißt, egal wann man darüber spricht, die parallele Berechnung scheint etwas zu sein, das in der Zukunft passieren wird.

Wird die Zukunft jemals damit Schritt halten? Seit mindestens 20 Jahren wird über parallele Berechnung als etwas Unmittelbares gesprochen, und sie hat die Programmierpraktiken bisher kaum beeinflusst. Oder doch? Bereits heute müssen Chiphersteller darüber nachdenken, und auch Leute, die Systemsoftware für Mehrprozessor-Computer schreiben, müssen es.

Die eigentliche Frage ist, wie weit die Parallelität in der Abstraktionsleiter nach oben gehen wird. Wird sie in hundert Jahren selbst Anwendungsprogrammierer betreffen? Oder wird es etwas sein, worüber sich Compiler-Schreiber Gedanken machen, das aber in den Quellcodes von Anwendungen normalerweise unsichtbar bleibt?

Eine Sache, die wahrscheinlich eintreffen wird, ist, dass die meisten Möglichkeiten für Parallelität verschwendet werden. Dies ist ein Sonderfall meiner allgemeineren Vorhersage, dass der größte Teil der zusätzlichen Rechenleistung, die uns zur Verfügung gestellt wird, verschwendet wird. Ich erwarte, dass so wie die stupende Geschwindigkeit der zugrunde liegenden Hardware, auch die Parallelität etwas sein wird, das nur dann genutzt wird, wenn man es explizit anfordert, ansonsten aber nicht verwendet wird. Das bedeutet, 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, wie Prozesse parallel ausführen zu können.

Und dies wird, wie das Anfordern spezifischer Implementierungen von Datenstrukturen, etwas sein, das Sie relativ spät im Leben eines Programms tun, wenn Sie versuchen, es zu optimieren. Version 1 wird normalerweise alle Vorteile, die sich aus der Parallelverarbeitung ergeben, ignorieren, genauso wie sie Vorteile, die sich aus bestimmten Datenrepräsentationen ergeben, ignorieren wird.

Außer in besonderen Anwendungsarten wird Parallelität die Programme, die in hundert Jahren geschrieben werden, nicht durchdringen. Es wäre eine verfrühte Optimierung, wenn es so wäre.

Wie viele Programmiersprachen wird es in hundert Jahren geben? Es scheint in letzter Zeit eine Vielzahl neuer Programmiersprachen zu geben. Ein Teil des Grundes dafür ist, dass schnellere Hardware es Programmierern ermöglicht hat, je nach Anwendung unterschiedliche Kompromisse zwischen Geschwindigkeit und Bequemlichkeit einzugehen. Wenn dies ein echter Trend ist, sollte die Hardware, die wir in hundert Jahren haben werden, dies nur verstärken.

Und doch könnte es in hundert Jahren nur wenige weit verbreitete Sprachen geben. Ein Teil des Grundes, warum ich das sage, ist Optimismus: Es scheint, als könnte man, wenn man einen wirklich guten Job macht, eine Sprache entwickeln, die ideal zum Schreiben einer langsamen Version 1 geeignet ist, aber mit der richtigen Optimierungsanleitung für den Compiler auch sehr schnellen Code liefern würde, wenn nötig. Da ich also optimistisch bin, werde ich vorhersagen, dass Programmierer in hundert Jahren, trotz der riesigen Lücke, die sie zwischen akzeptabler und maximaler Effizienz haben werden, Sprachen haben werden, die den Großteil davon abdecken können.

Je größer diese Lücke wird, desto wichtiger werden Profiler. Profiling wird derzeit noch wenig Beachtung geschenkt. Viele Menschen scheinen immer noch zu glauben, dass der Weg zu schnellen Anwendungen darin besteht, Compiler zu schreiben, die schnellen Code erzeugen. Je größer die Lücke zwischen akzeptabler und maximaler Leistung wird, desto klarer wird es, dass der Weg zu schnellen Anwendungen darin besteht, einen guten Leitfaden von dem einen zum anderen zu haben.

Wenn ich sage, dass es vielleicht nur wenige Sprachen geben wird, 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 weiter ausbreiten werden. Aber ich erwarte, dass sie so dünn sein werden, dass die Benutzer die darunterliegende allgemeine Programmiersprache sehen können.

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

Es stimmt nicht, dass diejenigen, die es nicht können, lehren (einige der besten Hacker, die ich kenne, sind Professoren), aber es stimmt, dass es viele Dinge gibt, die diejenigen, die lehren, nicht können. Forschung verhängt einschränkende Kastenbeschränkungen. 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 meist darauf, wie intellektuell die Arbeit klingt, wenn sie in Forschungsarbeiten beschrieben wird, anstatt darauf, wie wichtig sie für das Erzielen guter Ergebnisse ist. Der Extremfall ist wahrscheinlich die Literatur; Menschen, die Literatur studieren, sagen selten etwas, das für diejenigen, die sie produzieren, von irgendeinem Nutzen wäre.

Obwohl die Situation in den Naturwissenschaften besser ist, ist die Überschneidung zwischen der Art von Arbeit, die man tun darf, und der Art von Arbeit, die zu guten Sprachen führt, erschreckend klein. (Olin Shivers hat eloquent darüber gemurrt.) Zum Beispiel scheinen Typen eine unerschöpfliche Quelle für Forschungsarbeiten zu sein, obwohl statische Typisierung wahre Makros auszuschließen 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 und nicht als "Forschung", sondern auch dahin, dass Sprachen von den Anwendungsprogrammierern entworfen werden, die sie verwenden müssen, und nicht von Compilerschreibern. Das scheint ein guter Trend zu sein, und ich erwarte, dass er sich fortsetzen wird.

Im Gegensatz zur Physik in hundert Jahren, die fast notwendigerweise unmöglich vorherzusagen ist, denke ich, dass es prinzipiell möglich sein könnte, eine Sprache zu entwerfen, die Anwender in hundert Jahren ansprechen würde.

Eine Möglichkeit, eine Sprache zu entwerfen, besteht darin, einfach das Programm aufzuschreiben, das man gerne schreiben möchte, unabhängig davon, ob es einen Compiler gibt, der es übersetzen kann, oder Hardware, die es ausführen kann. Wenn man das tut, kann man von unbegrenzten Ressourcen ausgehen. Es scheint, als könnten wir uns heute genauso gut wie in hundert Jahren unbegrenzte Ressourcen vorstellen.

Was für ein Programm möchte man denn schreiben? Dasjenige, das am wenigsten Arbeit erfordert. Aber nicht ganz: dasjenige, das am wenigsten Arbeit erfordern würde, wenn unsere Vorstellungen über das Programmieren nicht schon durch die Sprachen beeinflusst wären, an die wir gewöhnt sind. Dieser Einfluss kann so allgegenwärtig sein, dass es große Anstrengungen erfordert, ihn zu überwinden. Man sollte meinen, es wäre für Geschöpfe, 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, so begrenzt durch die Sprache, in der wir denken, dass leichtere Formulierungen von Programmen sehr überraschend erscheinen. Das sind Dinge, die man entdecken muss, keine Dinge, in die man natürlich hineinfällt.

Ein hilfreicher Trick ist es hier, die Länge des Programms als Annäherung dafür zu verwenden, wie viel Arbeit es ist, es zu schreiben. Nicht die Länge in Zeichen natürlich, sondern die Länge in unterschiedlichen syntaktischen Elementen - im Grunde die Größe des Syntaxbaums. Es mag nicht ganz stimmen, dass das kürzeste Programm am wenigsten Arbeit erfordert, aber es ist nah genug dran, dass man besser darauf abzielt, die solide Zielgröße der Kürze zu treffen, als auf das unscharfe, nahegelegene Ziel des geringsten Aufwands. Dann wird der Algorithmus für das Sprachdesign: Schauen Sie sich ein Programm an und fragen Sie sich, gibt es eine Möglichkeit, es kürzer zu schreiben?

In der Praxis wird das Schreiben von Programmen in einer imaginären Sprache in hundert Jahren in unterschiedlichem Maße funktionieren, je nachdem, wie nah man am Kern ist. Sortierroutinen können Sie jetzt schreiben. Aber es wäre schwierig, jetzt vorherzusagen, welche Arten von Bibliotheken in hundert Jahren benötigt werden könnten. Vermutlich werden viele Bibliotheken für Domänen sein, die es noch gar nicht gibt. Wenn SETI@home funktioniert, werden wir zum Beispiel Bibliotheken zum Kommunizieren mit Außerirdischen brauchen. Es sei denn, sie sind so weit fortgeschritten, dass sie bereits in XML kommunizieren.

Am anderen Ende denke ich, dass man den Kern der Sprache heute entwerfen könnte. Tatsächlich könnte man argumentieren, dass er im Grunde schon 1958 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 ein Blick zurück. Wenn die heutigen Programmiersprachen 1960 verfügbar gewesen wären, hätte jemand sie dann benutzen wollen?

In mancher Hinsicht lautet die Antwort nein. Heutige Sprachen setzen Infrastruktur voraus, die 1960 nicht existierte. Eine Sprache, in der Einrückungen bedeutsam sind, wie Python, hätte auf Druckerterminals nicht gut funktioniert. Aber abgesehen von solchen Problemen - nehmen wir an, alle Programme wären nur auf Papier geschrieben worden - hätten Programmierer der 1960er Jahre die Sprachen, die wir heute benutzen, gemocht?

Ich denke schon. Einige der weniger fantasievollen, die Artefakte früher Sprachen in ihre Vorstellung von einem Programm eingebaut hatten, hätten Schwierigkeiten gehabt. (Wie kann man Daten manipulieren ohne Zeigermathematik? Wie kann man Flussdiagramme ohne Sprünge umsetzen?) Aber ich denke, die klügsten Programmierer hätten keine Probleme gehabt, die heutigen Sprachen bestmöglich zu nutzen, wenn sie sie gehabt hätten.

Wenn wir die hundertjährige Sprache jetzt hätten, wäre sie zumindest ein großartiger Pseudocode. Aber was ist mit ihrer Verwendung zum Schreiben von Software? Da die hundertjährige Sprache für manche Anwendungen schnellen Code erzeugen muss, könnte sie vermutlich effizient genug Code generieren, um auf unserer Hardware akzeptabel zu laufen. Wir müssten den Nutzern vielleicht mehr Optimierungshinweise geben als Nutzer in hundert Jahren, aber es wäre trotzdem ein Gewinn.

Nun haben wir zwei Ideen, die, wenn man sie kombiniert, interessante Möglichkeiten nahelegen: (1) die hundertjährige Sprache könnte prinzipiell heute entworfen werden, und (2) eine solche Sprache wäre, wenn es sie gäbe, gut zum Programmieren heute. Wenn man diese Ideen so dargelegt sieht, ist es schwer, nicht zu denken: Warum versuchen wir nicht, die hundertjährige Sprache jetzt zu schreiben?

Wenn man an Sprachdesign arbeitet, denke ich, ist es gut, ein solches Ziel zu haben und es bewusst im Hinterkopf zu behalten. Beim Autofahren lernt man eines der Prinzipien, das Auto nicht durch Ausrichten der Motorhaube an den auf der Straße aufgemalten Streifen auszurichten, sondern auf einen Punkt in der Ferne zu zielen. Auch wenn es einem nur um die nächsten zehn Fuß geht, ist das die richtige Antwort. Ich denke, wir können und sollten dasselbe mit Programmiersprachen tun.

Anmerkungen

Ich glaube, Lisp Machine Lisp war die erste Sprache, die das Prinzip verkörperte, dass Deklarationen (außer denen dynamischer Variablen) nur Optimierungshinweise sind und die Bedeutung eines korrekten Programms nicht ändern. Common Lisp scheint die erste gewesen zu sein, die dies explizit aussprach.

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 den Rest des Python-Teams für die Einladung, auf der PyCon zu sprechen.