Beliebt sein
Mai 2001
(Dieser Artikel wurde als eine Art Geschäftsplan für eine neue Sprache geschrieben. Daher fehlt ihm (weil sie als selbstverständlich angesehen wird) die wichtigste Eigenschaft einer guten Programmiersprache: sehr mächtige Abstraktionen.)
Ein Freund erzählte einmal einem angesehenen Experten für Betriebssysteme, dass er eine wirklich gute Programmiersprache entwerfen wolle. Der Experte sagte ihm, dass dies Zeitverschwendung sei, dass Programmiersprachen nicht aufgrund ihrer Verdienste populär oder unpopulär werden, und dass daher niemand seine Sprache nutzen würde, egal wie gut sie sei. Zumindest sei das mit der Sprache passiert, die er entworfen hatte.
Was macht eine Sprache populär? Verdienen populäre Sprachen ihre Popularität? Lohnt es sich, eine gute Programmiersprache zu definieren? Wie würde man das tun?
Ich denke, die Antworten auf diese Fragen finden sich, wenn man sich Hacker ansieht und lernt, was sie wollen. Programmiersprachen sind für Hacker, und eine Programmiersprache ist gut als Programmiersprache (anstatt beispielsweise als Übung in denotationaler Semantik oder Compilerbau), wenn und nur wenn Hacker sie mögen.
1 Die Mechanik der Popularität
Es stimmt sicherlich, dass die meisten Leute Programmiersprachen nicht einfach nach ihren Verdiensten auswählen. Die meisten Programmierer werden von jemand anderem angewiesen, welche Sprache sie verwenden sollen. Und doch glaube ich, dass der Einfluss solcher externen Faktoren auf die Popularität von Programmiersprachen nicht so groß ist, wie manchmal angenommen wird. Ich denke, ein größeres Problem ist, dass die Vorstellung eines Hackers von einer guten Programmiersprache nicht dieselbe ist wie die der meisten Sprachdesigner.
Zwischen den beiden ist die Meinung des Hackers diejenige, die zählt. Programmiersprachen sind keine Theoreme. Sie sind Werkzeuge, für Menschen entworfen, und sie müssen genauso auf menschliche Stärken und Schwächen zugeschnitten sein wie Schuhe auf menschliche Füße. Wenn ein Schuh beim Anziehen drückt, ist es ein schlechter Schuh, egal wie elegant er als Skulptur sein mag.
Es mag sein, dass die Mehrheit der Programmierer eine gute Sprache nicht von einer schlechten unterscheiden kann. Aber das ist bei jedem anderen Werkzeug nicht anders. Das bedeutet nicht, dass es Zeitverschwendung ist, den Entwurf einer guten Sprache zu versuchen. Experten-Hacker können eine gute Sprache erkennen, wenn sie sie sehen, und sie werden sie benutzen. Experten-Hacker sind zugegebenermaßen eine winzige Minderheit, aber diese winzige Minderheit schreibt die gesamte gute Software, und ihr Einfluss ist so groß, dass der Rest der Programmierer dazu neigt, jede Sprache zu verwenden, die sie verwenden. Oft ist es nicht nur Einfluss, sondern Befehl: Oft sind die Experten-Hacker genau die Leute, die als Chefs oder akademische Berater den anderen Programmierern sagen, welche Sprache sie verwenden sollen.
Die Meinung von Experten-Hackern ist nicht die einzige Kraft, die die relative Popularität von Programmiersprachen bestimmt – Legacy-Software (Cobol) und Hype (Ada, Java) spielen ebenfalls eine Rolle –, aber ich denke, sie ist auf lange Sicht die mächtigste Kraft. Angesichts einer anfänglichen kritischen Masse und genügend Zeit wird eine Programmiersprache wahrscheinlich so populär, wie sie es verdient. Und Popularität trennt gute Sprachen weiter von schlechten, denn Feedback von echten Benutzern führt immer zu Verbesserungen. Sehen Sie, wie stark sich jede populäre Sprache im Laufe ihres Lebens verändert hat. Perl und Fortran sind extreme Fälle, aber selbst Lisp hat sich stark verändert. Lisp 1.5 hatte zum Beispiel keine Makros; diese entwickelten sich später, nachdem Hacker am MIT ein paar Jahre damit verbracht hatten, Lisp zum Schreiben echter Programme zu verwenden.[1]
Ob eine Sprache gut sein muss, um populär zu sein, oder nicht, ich denke, eine Sprache muss populär sein, um gut zu sein. Und sie muss populär bleiben, um gut zu bleiben. Der Stand der Technik bei Programmiersprachen bleibt nicht stehen. Und doch sind die Lisps, die wir heute haben, immer noch ziemlich das, was sie am MIT Mitte der 1980er Jahre hatten, denn das ist das letzte Mal, dass Lisp eine ausreichend große und anspruchsvolle Benutzerbasis hatte.
Natürlich müssen Hacker von einer Sprache wissen, bevor sie sie benutzen können. Wie sollen sie davon erfahren? Von anderen Hackern. Aber es muss eine anfängliche Gruppe von Hackern geben, die die Sprache benutzt, damit andere überhaupt davon erfahren. Ich frage mich, wie groß diese Gruppe sein muss; wie viele Benutzer machen eine kritische Masse aus? Aus dem Stegreif würde ich sagen zwanzig. Wenn eine Sprache zwanzig einzelne Benutzer hätte, also zwanzig Benutzer, die sich aus eigenem Antrieb dafür entscheiden, sie zu benutzen, würde ich sie als real betrachten.
Das Erreichen dieses Ziels kann nicht einfach sein. Es würde mich nicht überraschen, wenn es schwieriger ist, von Null auf zwanzig zu kommen als von zwanzig auf tausend. Der beste Weg, diese anfänglichen zwanzig Benutzer zu gewinnen, ist wahrscheinlich die Verwendung eines Trojanischen Pferdes: den Leuten eine Anwendung zu geben, die sie wollen und die zufällig in der neuen Sprache geschrieben ist.
2 Externe Faktoren
Beginnen wir damit, einen externen Faktor anzuerkennen, der die Popularität einer Programmiersprache beeinflusst. Um populär zu werden, muss eine Programmiersprache die Skriptsprache eines populären Systems sein. Fortran und Cobol waren die Skriptsprachen früher IBM-Großrechner. C war die Skriptsprache von Unix, und später auch Perl. Tcl ist die Skriptsprache von Tk. Java und Javascript sind als Skriptsprachen für Webbrowser konzipiert.
Lisp ist keine massiv populäre Sprache, weil es nicht die Skriptsprache eines massiv populären Systems ist. Die Popularität, die es behält, stammt aus den 1960er und 1970er Jahren, als es die Skriptsprache des MIT war. Viele der damaligen großartigen Programmierer waren irgendwann mit dem MIT verbunden. Und in den frühen 1970er Jahren, vor C, war Lisps Dialekt am MIT, MacLisp genannt, eine der wenigen Programmiersprachen, die ein ernsthafter Hacker nutzen wollte.
Heute ist Lisp die Skriptsprache von zwei mäßig populären Systemen, Emacs und Autocad, und aus diesem Grund vermute ich, dass die meiste Lisp-Programmierung heute in Emacs Lisp oder AutoLisp erfolgt.
Programmiersprachen existieren nicht isoliert. Hacking ist ein transitives Verb – Hacker hacken normalerweise etwas – und in der Praxis werden Sprachen relativ zu dem beurteilt, wozu sie verwendet werden. Wenn Sie also eine populäre Sprache entwerfen wollen, müssen Sie entweder mehr als nur eine Sprache anbieten oder Ihre Sprache so entwerfen, dass sie die Skriptsprache eines bestehenden Systems ersetzt.
Common Lisp ist teilweise unbeliebt, weil es eine Waise ist. Es kam ursprünglich mit einem System zum Hacking: der Lisp Machine. Aber Lisp Machines (zusammen mit parallelen Computern) wurden in den 1980er Jahren von der zunehmenden Leistung allgemeiner Prozessoren überrollt. Common Lisp wäre vielleicht populär geblieben, wenn es eine gute Skriptsprache für Unix gewesen wäre. Es ist leider eine abscheulich schlechte.
Eine Möglichkeit, diese Situation zu beschreiben, ist zu sagen, dass eine Sprache nicht nach ihren eigenen Verdiensten beurteilt wird. Eine andere Ansicht ist, dass eine Programmiersprache wirklich keine Programmiersprache ist, es sei denn, sie ist auch die Skriptsprache von etwas. Das erscheint nur unfair, wenn es als Überraschung kommt. Ich denke, es ist nicht unfairer, als von einer Programmiersprache zu erwarten, dass sie beispielsweise eine Implementierung hat. Es ist einfach Teil dessen, was eine Programmiersprache ist.
Eine Programmiersprache benötigt natürlich eine gute Implementierung, und diese muss kostenlos sein. Unternehmen zahlen für Software, aber einzelne Hacker nicht, und es sind die Hacker, die Sie anziehen müssen.
Eine Sprache benötigt auch ein Buch darüber. Das Buch sollte dünn, gut geschrieben und voller guter Beispiele sein. K&R ist hier das Ideal. Im Moment würde ich fast sagen, dass eine Sprache ein Buch von O'Reilly veröffentlicht haben muss. Das wird zum Test dafür, ob man für Hacker wichtig ist.
Es sollte auch Online-Dokumentation geben. Tatsächlich kann das Buch als Online-Dokumentation beginnen. Aber ich glaube nicht, dass physische Bücher bereits veraltet sind. Ihr Format ist praktisch, und die De-facto-Zensur durch Verlage ist ein nützlicher, wenn auch unvollkommener Filter. Buchhandlungen sind einer der wichtigsten Orte, um etwas über neue Sprachen zu erfahren.
3 Kürze
Wenn Sie die drei Dinge bereitstellen können, die jede Sprache benötigt – eine kostenlose Implementierung, ein Buch und etwas zum Hacken –, wie machen Sie eine Sprache, die Hacker mögen?
Eine Sache, die Hacker mögen, ist Kürze. Hacker sind faul, auf die gleiche Weise, wie Mathematiker und moderne Architekten faul sind: Sie hassen alles Überflüssige. Es wäre nicht weit von der Wahrheit entfernt zu sagen, dass ein Hacker, der ein Programm schreiben will, unbewusst die Sprache danach auswählt, wie viele Zeichen er insgesamt tippen muss. Wenn Hacker nicht genau so denken, wäre es gut, wenn ein Sprachdesigner so tun würde, als ob.
Es ist ein Fehler, zu versuchen, den Benutzer mit langatmigen Ausdrücken zu bevormunden, die Englisch ähneln sollen. Cobol ist berüchtigt für diesen Fehler. Ein Hacker würde es als Beleidigung seiner Intelligenz und als Gotteslästerung betrachten, aufgefordert zu werden, zu schreiben:
z = x + y
anstatt
add x to y giving z
Es wurde manchmal gesagt, dass Lisp first und rest anstelle von car und cdr verwenden sollte, weil es Programme leichter lesbar machen würde. Vielleicht für die ersten paar Stunden. Aber ein Hacker kann schnell genug lernen, dass car das erste Element einer Liste bedeutet und cdr den Rest. Die Verwendung von first und rest bedeutet 50 % mehr Tipparbeit. Und sie haben auch unterschiedliche Längen, was bedeutet, dass die Argumente nicht übereinstimmen, wenn sie auf aufeinanderfolgenden Zeilen aufgerufen werden. Ich habe festgestellt, dass die Ausrichtung von Code auf der Seite viel ausmacht. Ich kann Lisp-Code kaum lesen, wenn er in einer Schriftart mit variabler Breite gesetzt ist, und Freunde sagen, dass dies auch für andere Sprachen gilt.
Kürze ist ein Bereich, in dem stark typisierte Sprachen verlieren. Bei gleichen anderen Bedingungen möchte niemand ein Programm mit einer Reihe von Deklarationen beginnen. Alles, was implizit sein kann, sollte es sein.
Auch die einzelnen Token sollten kurz sein. Perl und Common Lisp nehmen hier entgegengesetzte Pole ein. Perl-Programme können fast kryptisch dicht sein, während die Namen der eingebauten Common Lisp-Operatoren komisch lang sind. Die Designer von Common Lisp erwarteten wahrscheinlich, dass Benutzer Texteditoren verwenden, die diese langen Namen für sie eingeben. Aber die Kosten eines langen Namens sind nicht nur die Kosten des Tippens. Es gibt auch die Kosten des Lesens und die Kosten des Platzes, den er auf Ihrem Bildschirm einnimmt.
4 Hackbarkeit
Es gibt eine Sache, die für einen Hacker wichtiger ist als Kürze: die Fähigkeit, das zu tun, was man will. In der Geschichte der Programmiersprachen ging überraschend viel Aufwand in die Verhinderung, dass Programmierer Dinge tun, die als unangemessen gelten. Das ist ein gefährlich anmaßender Plan. Woher soll der Sprachdesigner wissen, was der Programmierer tun muss? Ich denke, Sprachdesigner wären besser beraten, ihren Zielbenutzer als Genie zu betrachten, das Dinge tun muss, die sie nie vorhergesehen haben, anstatt als Tollpatsch, der vor sich selbst geschützt werden muss. Der Tollpatsch wird sich sowieso ins eigene Fleisch schneiden. Sie können ihn davon abhalten, auf Variablen in einem anderen Paket zuzugreifen, aber Sie können ihn nicht davon abhalten, ein schlecht gestaltetes Programm zu schreiben, um das falsche Problem zu lösen, und ewig dafür zu brauchen.
Gute Programmierer wollen oft gefährliche und unappetitliche Dinge tun. Mit unappetitlich meine ich Dinge, die hinter der semantischen Fassade, die die Sprache zu präsentieren versucht, verschwinden: zum Beispiel die interne Darstellung einer High-Level-Abstraktion zu erhalten. Hacker wollen hacken, und Hacking bedeutet, in Dinge hineinzugehen und den ursprünglichen Designer zu hinterfragen.
Lassen Sie sich hinterfragen. Wenn Sie ein Werkzeug herstellen, nutzen die Leute es auf eine Weise, die Sie nicht beabsichtigt haben, und das gilt insbesondere für ein hochartikuliertes Werkzeug wie eine Programmiersprache. Viele Hacker werden Ihr semantisches Modell auf eine Weise verändern wollen, die Sie sich nie vorgestellt haben. Ich sage, lassen Sie sie; geben Sie dem Programmierer Zugriff auf so viele interne Dinge, wie Sie können, ohne Laufzeitsysteme wie den Garbage Collector zu gefährden.
In Common Lisp wollte ich oft durch die Felder einer Struktur iterieren – zum Beispiel Referenzen auf ein gelöschtes Objekt auskämmen oder Felder finden, die nicht initialisiert sind. Ich weiß, dass die Strukturen darunter nur Vektoren sind. Und doch kann ich keine allgemeine Funktion schreiben, die ich auf jede Struktur anwenden kann. Ich kann nur auf die Felder nach Namen zugreifen, weil eine Struktur dafür gedacht ist, das zu bedeuten.
Ein Hacker möchte vielleicht nur ein- oder zweimal in einem großen Programm das beabsichtigte Modell untergraben. Aber was für einen Unterschied es macht, es tun zu können. Und es kann mehr als nur ein Problem sein, das gelöst wird. Hier gibt es auch eine Art von Vergnügen. Hacker teilen das geheime Vergnügen des Chirurgen, in den groben Innereien herumzustochern, das geheime Vergnügen des Teenagers, Pickel auszudrücken.[2] Für Jungen zumindest sind bestimmte Arten von Schrecken faszinierend. Maxim Magazine veröffentlicht jedes Jahr einen Bildband mit einer Mischung aus Pin-ups und grausamen Unfällen. Sie kennen ihr Publikum.
Historisch gesehen war Lisp gut darin, Hackern ihren Willen zu lassen. Die politische Korrektheit von Common Lisp ist eine Aberration. Frühe Lisps ließen Sie alles in die Hand nehmen. Ein Großteil dieses Geistes ist glücklicherweise in Makros erhalten geblieben. Was für eine wunderbare Sache, beliebige Transformationen am Quellcode vornehmen zu können.
Klassische Makros sind ein echtes Hacker-Werkzeug – einfach, mächtig und gefährlich. Es ist so einfach zu verstehen, was sie tun: Sie rufen eine Funktion mit den Argumenten des Makros auf, und was auch immer sie zurückgibt, wird anstelle des Makroaufrufs eingefügt. Hygienische Makros verkörpern das Gegenteil. Sie versuchen, Sie vor dem Verständnis dessen zu schützen, was sie tun. Ich habe noch nie gehört, dass hygienische Makros in einem Satz erklärt wurden. Und sie sind ein klassisches Beispiel für die Gefahren, zu entscheiden, was Programmierer wollen dürfen. Hygienische Makros sollen mich unter anderem vor Variablenerfassung schützen, aber Variablenerfassung ist genau das, was ich in einigen Makros will.
Eine wirklich gute Sprache sollte sowohl sauber als auch schmutzig sein: sauber entworfen, mit einem kleinen Kern aus gut verstandenen und hochgradig orthogonalen Operatoren, aber schmutzig in dem Sinne, dass sie Hackern ihren Willen lässt. C ist so. Die frühen Lisps auch. Eine echte Hacker-Sprache wird immer einen leicht zwielichtigen Charakter haben.
Eine gute Programmiersprache sollte Funktionen haben, die die Leute, die den Ausdruck „Software-Engineering“ verwenden, missbilligend die Köpfe schütteln lassen. Am anderen Ende des Kontinuums stehen Sprachen wie Ada und Pascal, Modelle der Sittsamkeit, die sich gut zum Lehren eignen und sonst nicht viel.
5 Wegwerfprogramme
Um für Hacker attraktiv zu sein, muss eine Sprache gut für das Schreiben der Arten von Programmen sein, die sie schreiben wollen. Und das bedeutet, vielleicht überraschenderweise, dass sie gut für das Schreiben von Wegwerfprogrammen sein muss.
Ein Wegwerfprogramm ist ein Programm, das man schnell für eine bestimmte Aufgabe schreibt: ein Programm zur Automatisierung einer Systemverwaltungsaufgabe, zur Generierung von Testdaten für eine Simulation oder zur Konvertierung von Daten von einem Format in ein anderes. Das Überraschende an Wegwerfprogrammen ist, dass sie, wie die „temporären“ Gebäude, die an vielen amerikanischen Universitäten während des Zweiten Weltkriegs gebaut wurden, oft nicht weggeworfen werden. Viele entwickeln sich zu echten Programmen mit echten Funktionen und echten Benutzern.
Ich habe die Ahnung, dass die besten großen Programme auf diese Weise beginnen, anstatt von Anfang an groß konzipiert zu werden, wie der Hoover-Damm. Es ist beängstigend, etwas Großes von Grund auf neu zu bauen. Wenn Menschen ein zu großes Projekt übernehmen, werden sie überwältigt. Das Projekt gerät entweder ins Stocken, oder das Ergebnis ist steril und hölzern: ein Einkaufszentrum statt einer echten Innenstadt, Brasília statt Rom, Ada statt C.
Eine andere Möglichkeit, ein großes Programm zu erhalten, ist, mit einem Wegwerfprogramm zu beginnen und es ständig zu verbessern. Dieser Ansatz ist weniger entmutigend, und das Design des Programms profitiert von der Weiterentwicklung. Ich denke, wenn man nachschauen würde, würde sich herausstellen, dass dies der Weg ist, wie die meisten großen Programme entwickelt wurden. Und diejenigen, die sich auf diese Weise entwickelt haben, werden wahrscheinlich immer noch in der Sprache geschrieben, in der sie ursprünglich geschrieben wurden, da es selten ist, dass ein Programm portiert wird, außer aus politischen Gründen. Und so muss man paradoxerweise, wenn man eine Sprache machen will, die für große Systeme verwendet wird, sie gut für das Schreiben von Wegwerfprogrammen machen, denn dort kommen große Systeme her.
Perl ist ein eindrucksvolles Beispiel für diese Idee. Es wurde nicht nur für das Schreiben von Wegwerfprogrammen entwickelt, sondern war selbst ziemlich ein Wegwerfprogramm. Perl begann als Sammlung von Dienstprogrammen zur Berichterstellung und entwickelte sich erst zu einer Programmiersprache, als die Wegwerfprogramme, die die Leute darin schrieben, größer wurden. Erst mit Perl 5 (wenn überhaupt) war die Sprache für das Schreiben ernsthafter Programme geeignet, und doch war sie bereits massiv populär.
Was macht eine Sprache gut für Wegwerfprogramme? Zunächst muss sie leicht verfügbar sein. Ein Wegwerfprogramm ist etwas, das man voraussichtlich in einer Stunde schreibt. Die Sprache muss also wahrscheinlich bereits auf dem Computer installiert sein, den man benutzt. Sie kann nicht etwas sein, das man installieren muss, bevor man es benutzt. Sie muss da sein. C war da, weil es mit dem Betriebssystem kam. Perl war da, weil es ursprünglich ein Werkzeug für Systemadministratoren war und Ihr Administrator es bereits installiert hatte.
Verfügbar zu sein bedeutet jedoch mehr als nur installiert zu sein. Eine interaktive Sprache mit einer Kommandozeilenschnittstelle ist verfügbarer als eine, die man separat kompilieren und ausführen muss. Eine populäre Programmiersprache sollte interaktiv sein und schnell starten.
Eine weitere Sache, die man in einem Wegwerfprogramm möchte, ist Kürze. Kürze ist für Hacker immer attraktiv, und nie mehr als in einem Programm, das sie voraussichtlich in einer Stunde fertigstellen werden.
6 Bibliotheken
Die ultimative Kürze besteht natürlich darin, das Programm bereits geschrieben zu haben und es lediglich aufzurufen. Und das bringt uns zu dem, was meiner Meinung nach ein immer wichtigeres Merkmal von Programmiersprachen sein wird: Bibliotheksfunktionen. Perl gewinnt, weil es große Bibliotheken zur Manipulation von Zeichenketten hat. Diese Klasse von Bibliotheksfunktionen ist besonders wichtig für Wegwerfprogramme, die oft ursprünglich zur Konvertierung oder Extraktion von Daten geschrieben werden. Viele Perl-Programme beginnen wahrscheinlich nur als ein paar zusammengefügte Bibliotheksaufrufe.
Ich denke, viele der Fortschritte, die in den nächsten fünfzig Jahren in Programmiersprachen stattfinden werden, werden mit Bibliotheksfunktionen zu tun haben. Ich denke, zukünftige Programmiersprachen werden Bibliotheken haben, die genauso sorgfältig entworfen sind wie die Kernsprache. Das Design von Programmiersprachen wird sich nicht darum drehen, ob man seine Sprache stark oder schwach typisiert, objektorientiert oder funktional oder was auch immer macht, sondern darum, wie man großartige Bibliotheken entwirft. Die Art von Sprachdesignern, die gerne über den Entwurf von Typsystemen nachdenken, wird hier vielleicht erschaudern. Es ist fast wie das Schreiben von Anwendungen! Zu schlecht. Sprachen sind für Programmierer, und Bibliotheken sind das, was Programmierer brauchen.
Es ist schwer, gute Bibliotheken zu entwerfen. Es ist nicht nur eine Frage des Schreibens von viel Code. Sobald die Bibliotheken zu groß werden, kann es manchmal länger dauern, die benötigte Funktion zu finden, als den Code selbst zu schreiben. Bibliotheken müssen mit einem kleinen Satz von orthogonalen Operatoren entworfen werden, genau wie die Kernsprache. Es sollte für den Programmierer möglich sein, zu erraten, welcher Bibliotheksaufruf das tut, was er braucht.
Bibliotheken sind ein Bereich, in dem Common Lisp hinterherhinkt. Es gibt nur rudimentäre Bibliotheken zur Manipulation von Zeichenketten und fast keine zur Interaktion mit dem Betriebssystem. Aus historischen Gründen versucht Common Lisp so zu tun, als ob das Betriebssystem nicht existiert. Und weil man nicht mit dem Betriebssystem sprechen kann, ist es unwahrscheinlich, dass man ein ernsthaftes Programm nur mit den eingebauten Operatoren in Common Lisp schreiben kann. Man muss auch einige implementierungsspezifische Hacks verwenden, und in der Praxis geben diese einem nicht alles, was man will. Hacker würden Lisp viel höher einschätzen, wenn Common Lisp mächtige Zeichenkettenbibliotheken und gute Betriebssystemunterstützung hätte.
7 Syntax
Könnte eine Sprache mit Lisps Syntax, oder genauer gesagt, mangelnder Syntax, jemals populär werden? Ich kenne die Antwort auf diese Frage nicht. Ich denke, dass die Syntax nicht der Hauptgrund dafür ist, dass Lisp derzeit nicht populär ist. Common Lisp hat schlimmere Probleme als ungewohnte Syntax. Ich kenne mehrere Programmierer, die mit Präfix-Notation vertraut sind und dennoch standardmäßig Perl verwenden, weil es mächtige Zeichenkettenbibliotheken hat und mit dem Betriebssystem sprechen kann.
Es gibt zwei mögliche Probleme mit der Präfixnotation: dass sie für Programmierer ungewohnt ist und dass sie nicht dicht genug ist. Die konventionelle Weisheit in der Lisp-Welt ist, dass das erste Problem das eigentliche ist. Ich bin mir da nicht so sicher. Ja, Präfixnotation lässt normale Programmierer in Panik geraten. Aber ich glaube nicht, dass die Meinungen normaler Programmierer zählen. Sprachen werden populär oder unpopulär, basierend darauf, was Experten-Hacker von ihnen halten, und ich denke, Experten-Hacker könnten mit Präfixnotation umgehen. Perl-Syntax kann ziemlich unverständlich sein, aber das hat Perl nicht an seiner Popularität gehindert. Wenn überhaupt, hat es vielleicht zur Förderung eines Perl-Kults beigetragen.
Ein ernsteres Problem ist die Diffusität der Präfixnotation. Für Experten-Hacker ist das wirklich ein Problem. Niemand möchte (aref a x y) schreiben, wenn er a[x,y] schreiben könnte.
In diesem speziellen Fall gibt es eine Möglichkeit, das Problem zu umgehen. Wenn wir Datenstrukturen so behandeln, als wären sie Funktionen auf Indizes, könnten wir stattdessen (a x y) schreiben, was noch kürzer ist als die Perl-Form. Ähnliche Tricks können andere Arten von Ausdrücken verkürzen.
Wir können viele Klammern loswerden (oder optional machen), indem wir die Einrückung bedeutsam machen. So lesen Programmierer Code sowieso: Wenn die Einrückung etwas sagt und die Trennzeichen etwas anderes, halten wir uns an die Einrückung. Die Berücksichtigung der Einrückung würde diese häufige Fehlerquelle beseitigen und Programme kürzer machen.
Manchmal ist Infix-Syntax leichter zu lesen. Das gilt insbesondere für mathematische Ausdrücke. Ich habe mein ganzes Programmierleben Lisp verwendet und finde Präfix-Mathematikausdrücke immer noch nicht natürlich. Und doch ist es praktisch, besonders wenn man Code generiert, Operatoren zu haben, die beliebig viele Argumente annehmen. Wenn wir also Infix-Syntax haben, sollte sie wahrscheinlich als eine Art Read-Macro implementiert werden.
Ich glaube nicht, dass wir religiös dagegen sein sollten, Lisp Syntax hinzuzufügen, solange sie auf eine gut verstandene Weise in zugrunde liegende S-Ausdrücke übersetzt wird. Es gibt bereits eine ganze Menge Syntax in Lisp. Es ist nicht unbedingt schlecht, mehr einzuführen, solange niemand gezwungen ist, sie zu verwenden. In Common Lisp sind einige Trennzeichen für die Sprache reserviert, was darauf hindeutet, dass zumindest einige der Designer beabsichtigten, mehr Syntax in der Zukunft zu haben.
Eines der egregiösesten un-lispyen Syntaxelemente in Common Lisp findet sich in Format-Strings; Format ist eine eigene Sprache, und diese Sprache ist nicht Lisp. Wenn es einen Plan gäbe, mehr Syntax in Lisp einzuführen, könnten Format-Spezifizierer darin enthalten sein. Es wäre gut, wenn Makros Format-Spezifizierer generieren könnten, so wie sie jede andere Art von Code generieren.
Ein angesehener Lisp-Hacker sagte mir, dass sein Exemplar von CLTL bei der Sektion Format aufschlage. Meins auch. Das deutet wahrscheinlich auf Verbesserungspotenzial hin. Es könnte auch bedeuten, dass Programme viel I/O machen.
8 Effizienz
Eine gute Sprache sollte, wie jeder weiß, schnellen Code erzeugen. Aber in der Praxis glaube ich nicht, dass schneller Code hauptsächlich aus Dingen stammt, die man beim Entwurf der Sprache tut. Wie Knuth schon vor langer Zeit feststellte, ist Geschwindigkeit nur in bestimmten kritischen Engpässen wichtig. Und wie viele Programmierer seitdem beobachtet haben, irrt man sich sehr oft darüber, wo diese Engpässe liegen.
In der Praxis besteht der Weg zu schnellem Code darin, einen sehr guten Profiler zu haben, anstatt beispielsweise die Sprache stark typisiert zu machen. Sie müssen nicht den Typ jedes Arguments in jedem Aufruf im Programm kennen. Sie müssen die Typen der Argumente in den Engpässen deklarieren können. Und noch mehr müssen Sie herausfinden können, wo die Engpässe liegen.
Eine Beschwerde, die Leute über Lisp hatten, ist, dass es schwer ist zu sagen, was teuer ist. Das mag stimmen. Es mag auch unvermeidlich sein, wenn man eine sehr abstrakte Sprache haben möchte. Und auf jeden Fall denke ich, dass ein guter Profiler das Problem weitgehend beheben würde: Man würde bald lernen, was teuer ist.
Ein Teil des Problems hier ist sozial. Sprachdesigner schreiben gerne schnelle Compiler. So messen sie ihre Fähigkeiten. Sie betrachten den Profiler bestenfalls als Zusatz. Aber in der Praxis kann ein guter Profiler mehr zur Verbesserung der Geschwindigkeit tatsächlicher Programme, die in der Sprache geschrieben sind, beitragen als ein Compiler, der schnellen Code erzeugt. Auch hier sind Sprachdesigner etwas von ihren Benutzern entfremdet. Sie leisten wirklich gute Arbeit bei der Lösung des leicht falschen Problems.
Es könnte eine gute Idee sein, einen aktiven Profiler zu haben – Leistungsdaten an den Programmierer zu pushen, anstatt darauf zu warten, dass er danach fragt. Zum Beispiel könnte der Editor Engpässe rot anzeigen, wenn der Programmierer den Quellcode bearbeitet. Ein anderer Ansatz wäre, irgendwie darzustellen, was in laufenden Programmen passiert. Dies wäre ein besonders großer Gewinn bei serverbasierten Anwendungen, wo Sie viele laufende Programme haben, die Sie sich ansehen können. Ein aktiver Profiler könnte grafisch anzeigen, was im Speicher passiert, während ein Programm läuft, oder sogar Geräusche machen, die sagen, was passiert.
Ton ist ein guter Hinweis auf Probleme. An einem Ort, an dem ich gearbeitet habe, hatten wir eine große Tafel mit Anzeigen, die zeigten, was mit unseren Webservern passierte. Die Zeiger wurden von kleinen Servomotoren bewegt, die ein leises Geräusch machten, wenn sie sich drehten. Ich konnte die Tafel von meinem Schreibtisch aus nicht sehen, aber ich stellte fest, dass ich am Geräusch sofort erkennen konnte, wann es ein Problem mit einem Server gab.
Es könnte sogar möglich sein, einen Profiler zu schreiben, der ineffiziente Algorithmen automatisch erkennt. Es würde mich nicht überraschen, wenn sich bestimmte Muster des Speicherzugriffs als sichere Anzeichen für schlechte Algorithmen herausstellen würden. Wenn ein kleiner Kerl im Computer herumlaufen und unsere Programme ausführen würde, hätte er wahrscheinlich eine ebenso lange und klagende Geschichte über seinen Job zu erzählen wie ein Angestellter der Bundesregierung. Ich habe oft das Gefühl, dass ich den Prozessor auf viele wilde Gänsejagd schicke, aber ich hatte nie eine gute Möglichkeit zu sehen, was er tut.
Eine Reihe von Lisps kompiliert jetzt in Bytecode, der dann von einem Interpreter ausgeführt wird. Dies geschieht normalerweise, um die Implementierung leichter portierbar zu machen, könnte aber ein nützliches Sprachmerkmal sein. Es könnte eine gute Idee sein, den Bytecode zu einem offiziellen Teil der Sprache zu machen und es Programmierern zu erlauben, Inline-Bytecode in Engpässen zu verwenden. Dann wären solche Optimierungen auch portierbar.
Die Natur der Geschwindigkeit, wie sie vom Endbenutzer wahrgenommen wird, könnte sich ändern. Mit dem Aufkommen serverbasierter Anwendungen werden immer mehr Programme E/A-gebunden sein. Es wird sich lohnen, E/A schnell zu machen. Die Sprache kann hierbei mit einfachen Maßnahmen wie einfachen, schnellen, formatierten Ausgabefunktionen sowie mit tiefgreifenden strukturellen Änderungen wie Caching und persistenten Objekten helfen.
Benutzer interessieren sich für die Reaktionszeit. Aber eine andere Art von Effizienz wird immer wichtiger werden: die Anzahl der gleichzeitigen Benutzer, die Sie pro Prozessor unterstützen können. Viele der interessanten Anwendungen, die in naher Zukunft geschrieben werden, werden serverbasiert sein, und die Anzahl der Benutzer pro Server ist die kritische Frage für jeden, der solche Anwendungen hostet. Bei den Kapitalkosten eines Unternehmens, das eine serverbasierte Anwendung anbietet, ist dies der Divisor.
Jahrelang war Effizienz in den meisten Endbenutzeranwendungen nicht sehr wichtig. Entwickler konnten davon ausgehen, dass jeder Benutzer einen immer leistungsfähigeren Prozessor auf seinem Schreibtisch haben würde. Und nach Parkinsons Gesetz hat sich die Software ausgedehnt, um die verfügbaren Ressourcen zu nutzen. Das wird sich mit serverbasierten Anwendungen ändern. In dieser Welt werden Hardware und Software zusammen geliefert. Für Unternehmen, die serverbasierte Anwendungen anbieten, wird es einen großen Unterschied für das Endergebnis machen, wie viele Benutzer sie pro Server unterstützen können.
In einigen Anwendungen wird der Prozessor der limitierende Faktor sein, und die Ausführungsgeschwindigkeit wird das Wichtigste zur Optimierung sein. Aber oft wird der Speicher das Limit sein; die Anzahl der gleichzeitigen Benutzer wird durch die Menge des Speichers bestimmt, die Sie für die Daten jedes Benutzers benötigen. Die Sprache kann auch hier helfen. Gute Unterstützung für Threads ermöglicht es allen Benutzern, einen einzigen Heap zu teilen. Es kann auch hilfreich sein, persistente Objekte und/oder Sprachunterstützung für Lazy Loading zu haben.
9 Zeit
Die letzte Zutat, die eine populäre Sprache benötigt, ist Zeit. Niemand möchte Programme in einer Sprache schreiben, die verschwinden könnte, wie es viele Programmiersprachen tun. Daher werden die meisten Hacker dazu neigen, zu warten, bis eine Sprache ein paar Jahre existiert, bevor sie überhaupt daran denken, sie zu benutzen.
Erfinder wunderbarer neuer Dinge sind oft überrascht, das festzustellen, aber man braucht Zeit, um eine Botschaft an die Leute zu übermitteln. Ein Freund von mir tut selten etwas zum ersten Mal, wenn ihn jemand darum bittet. Er weiß, dass Leute manchmal nach Dingen fragen, die sie dann doch nicht wollen. Um seine Zeit nicht zu verschwenden, wartet er, bis er zum dritten oder vierten Mal darum gebeten wird; bis dahin ist derjenige, der ihn bittet, wahrscheinlich ziemlich verärgert, aber zumindest wollen sie wahrscheinlich wirklich, was auch immer sie fragen.
Die meisten Leute haben gelernt, eine ähnliche Filterung auf neue Dinge anzuwenden, von denen sie hören. Sie fangen erst an, darauf zu achten, wenn sie zehnmal davon gehört haben. Sie sind vollkommen im Recht: Die Mehrheit der angesagten neuen Was-auch-immer erweist sich als Zeitverschwendung und verschwindet schließlich. Indem ich das Erlernen von VRML verzögerte, vermied ich es, es überhaupt lernen zu müssen.
Wer also etwas Neues erfindet, muss damit rechnen, seine Botschaft jahrelang zu wiederholen, bevor die Leute anfangen, sie zu verstehen. Wir haben die, soweit ich weiß, erste webbasierte Anwendung geschrieben, und es hat Jahre gedauert, bis die Leute verstanden haben, dass sie nicht heruntergeladen werden musste. Sie waren nicht dumm. Sie haben uns einfach ausgeblendet.
Die gute Nachricht ist, einfache Wiederholung löst das Problem. Alles, was Sie tun müssen, ist, Ihre Geschichte weiterzuerzählen, und schließlich werden die Leute zuhören. Nicht, wenn die Leute bemerken, dass Sie da sind, achten sie auf Sie; sondern wenn sie bemerken, dass Sie immer noch da sind.
Es ist gut, dass es normalerweise eine Weile dauert, bis man an Fahrt gewinnt. Die meisten Technologien entwickeln sich auch nach ihrer Einführung noch stark weiter – insbesondere Programmiersprachen. Nichts könnte besser für eine neue Technologie sein, als ein paar Jahre lang nur von einer kleinen Anzahl von Early Adopters genutzt zu werden. Early Adopters sind anspruchsvoll und fordernd und beseitigen schnell alle verbleibenden Mängel Ihrer Technologie. Wenn Sie nur wenige Benutzer haben, können Sie mit allen in engem Kontakt stehen. Und Early Adopters sind nachsichtig, wenn Sie Ihr System verbessern, auch wenn dies zu einigen Brüchen führt.
Es gibt zwei Wege, wie neue Technologie eingeführt wird: die Methode des organischen Wachstums und die Methode des Big Bang. Die Methode des organischen Wachstums wird durch das klassische, aus dem Bauch heraus entwickelte, unterfinanzierte Garagen-Startup veranschaulicht. Ein paar Jungs, die im Verborgenen arbeiten, entwickeln eine neue Technologie. Sie starten sie ohne Marketing und haben anfangs nur wenige (fanatisch loyale) Benutzer. Sie verbessern die Technologie weiter, und währenddessen wächst ihre Benutzerbasis durch Mundpropaganda. Bevor sie es wissen, sind sie groß.
Der andere Ansatz, die Big-Bang-Methode, wird durch das VC-finanzierte, stark vermarktete Startup veranschaulicht. Sie eilen, um ein Produkt zu entwickeln, starten es mit großer Publicity und haben sofort (hoffentlich) eine große Benutzerbasis.
Im Allgemeinen beneiden die Garagen-Typen die Big-Bang-Typen. Die Big-Bang-Typen sind redegewandt und selbstbewusst und werden von den VCs respektiert. Sie können sich das Beste von allem leisten, und die PR-Kampagne rund um den Start hat den Nebeneffekt, sie zu Berühmtheiten zu machen. Die organisch wachsenden Typen, die in ihrer Garage sitzen, fühlen sich arm und unbeliebt. Und doch denke ich, dass sie sich oft zu Unrecht bemitleiden. Organisches Wachstum scheint bessere Technologie und reichere Gründer hervorzubringen als die Big-Bang-Methode. Wenn man sich die heute dominanten Technologien ansieht, wird man feststellen, dass die meisten von ihnen organisch gewachsen sind.
Dieses Muster gilt nicht nur für Unternehmen. Man sieht es auch in der geförderten Forschung. Multics und Common Lisp waren Big-Bang-Projekte, und Unix und MacLisp waren Projekte des organischen Wachstums.
10 Neugestaltung
„Das beste Schreiben ist Umschreiben“, schrieb E. B. White. Jeder gute Schriftsteller weiß das, und es gilt auch für Software. Der wichtigste Teil des Designs ist die Neugestaltung. Programmiersprachen werden besonders nicht genug neu gestaltet.
Um gute Software zu schreiben, müssen Sie gleichzeitig zwei gegensätzliche Ideen im Kopf behalten. Sie brauchen den naiven Glauben des jungen Hackers an seine Fähigkeiten und gleichzeitig den Skeptizismus des Veteranen. Sie müssen mit einer Gehirnhälfte denken können wie schwer kann das sein?, während Sie mit der anderen denken das wird nie funktionieren.
Der Trick besteht darin, zu erkennen, dass es keinen wirklichen Widerspruch gibt. Sie wollen optimistisch und skeptisch gegenüber zwei verschiedenen Dingen sein. Sie müssen optimistisch hinsichtlich der Möglichkeit sein, das Problem zu lösen, aber skeptisch hinsichtlich des Wertes der bisherigen Lösung.
Leute, die gute Arbeit leisten, denken oft, dass alles, woran sie arbeiten, nicht gut ist. Andere sehen, was sie getan haben, und sind voller Wunder, aber der Schöpfer ist voller Sorge. Dieses Muster ist kein Zufall: Es ist die Sorge, die die Arbeit gut gemacht hat.
Wenn Sie Hoffnung und Sorge im Gleichgewicht halten, treiben sie ein Projekt voran, genauso wie Ihre beiden Beine ein Fahrrad vorantreiben. In der ersten Phase des Zwei-Zyklus-Innovationsmotors arbeiten Sie fieberhaft an einem Problem, inspiriert von Ihrem Vertrauen, dass Sie es lösen können. In der zweiten Phase schauen Sie sich das Ergebnis im kalten Licht des Morgens an und sehen all seine Fehler sehr deutlich. Aber solange Ihr kritischer Geist Ihre Hoffnung nicht überwiegt, werden Sie Ihr zugegebenermaßen unvollständiges System betrachten und denken: Wie schwer kann es sein, den Rest zu erledigen?, und so den Zyklus fortsetzen.
Es ist schwierig, die beiden Kräfte im Gleichgewicht zu halten. Bei jungen Hackern überwiegt der Optimismus. Sie produzieren etwas, sind überzeugt, dass es großartig ist, und verbessern es nie. Bei alten Hackern überwiegt der Skeptizismus, und sie wagen es nicht einmal, ehrgeizige Projekte anzugehen.
Alles, was Sie tun können, um den Neugestaltungszyklus am Laufen zu halten, ist gut. Prosa kann immer wieder umgeschrieben werden, bis Sie damit zufrieden sind. Aber Software wird im Allgemeinen nicht genug neu gestaltet. Prosa hat Leser, aber Software hat Benutzer. Wenn ein Autor einen Aufsatz umschreibt, werden Leute, die die alte Version gelesen haben, wahrscheinlich nicht darüber klagen, dass ihre Gedanken durch eine neu eingeführte Inkompatibilität unterbrochen wurden.
Benutzer sind ein zweischneidiges Schwert. Sie können Ihnen helfen, Ihre Sprache zu verbessern, aber sie können Sie auch davon abhalten, sie zu verbessern. Wählen Sie Ihre Benutzer also sorgfältig aus und lassen Sie ihre Zahl nur langsam wachsen. Benutzer zu haben ist wie Optimierung: Der weise Weg ist, sie zu verzögern. Außerdem können Sie im Allgemeinen jederzeit mehr ändern, als Sie denken. Eine Änderung einzuführen ist wie das Abziehen eines Verbandes: Der Schmerz ist eine Erinnerung, sobald Sie ihn spüren.
Jeder weiß, dass es keine gute Idee ist, eine Sprache von einem Komitee entwerfen zu lassen. Komitees führen zu schlechtem Design. Aber ich denke, die größte Gefahr von Komitees ist, dass sie die Neugestaltung behindern. Es ist so viel Arbeit, Änderungen einzuführen, dass niemand sich die Mühe machen will. Was auch immer ein Komitee beschließt, bleibt so, auch wenn die meisten Mitglieder es nicht mögen.
Selbst ein Komitee von zwei Personen behindert die Neugestaltung. Dies geschieht insbesondere bei den Schnittstellen zwischen Softwareteilen, die von zwei verschiedenen Personen geschrieben wurden. Um die Schnittstelle zu ändern, müssen beide zustimmen, sie gleichzeitig zu ändern. Und so ändern sich Schnittstellen tendenziell gar nicht, was ein Problem ist, da sie tendenziell einer der am meisten Ad-hoc-Teile jedes Systems sind.
Eine Lösung hierfür könnte darin bestehen, Systeme so zu entwerfen, dass Schnittstellen horizontal statt vertikal sind – so dass Module immer vertikal gestapelte Abstraktionsebenen sind. Dann wird die Schnittstelle tendenziell von einem von ihnen besessen sein. Die untere von zwei Ebenen wird entweder eine Sprache sein, in der die obere geschrieben ist, in welchem Fall die untere Ebene die Schnittstelle besitzen wird, oder sie wird eine Slave sein, in welchem Fall die Schnittstelle von der oberen Ebene diktiert werden kann.
11 Lisp
Was all dies impliziert, ist, dass es Hoffnung für einen neuen Lisp gibt. Es gibt Hoffnung für jede Sprache, die Hackern gibt, was sie wollen, einschließlich Lisp. Ich denke, wir haben vielleicht einen Fehler gemacht, als wir dachten, dass Hacker von Lisps Seltsamkeit abgeschreckt werden. Diese tröstliche Illusion hat uns vielleicht davon abgehalten, das eigentliche Problem mit Lisp, oder zumindest Common Lisp, zu sehen, nämlich dass es schlecht darin ist, das zu tun, was Hacker tun wollen. Eine Hacker-Sprache benötigt mächtige Bibliotheken und etwas zum Hacken. Common Lisp hat beides nicht. Eine Hacker-Sprache ist kurz und hackbar. Common Lisp ist es nicht.
Die gute Nachricht ist, dass nicht Lisp schlecht ist, sondern Common Lisp. Wenn wir einen neuen Lisp entwickeln können, der eine echte Hacker-Sprache ist, denke ich, werden Hacker ihn benutzen. Sie werden jede Sprache benutzen, die die Arbeit erledigt. Alles, was wir tun müssen, ist sicherzustellen, dass dieser neue Lisp eine wichtige Aufgabe besser erledigt als andere Sprachen.
Die Geschichte bietet einige Ermutigungen. Im Laufe der Zeit haben aufeinanderfolgende neue Programmiersprachen immer mehr Funktionen von Lisp übernommen. Es gibt nicht mehr viel zu kopieren, bevor die Sprache, die man gemacht hat, Lisp ist. Die neueste angesagte Sprache, Python, ist ein verwässertes Lisp mit Infix-Syntax und ohne Makros. Ein neuer Lisp wäre ein natürlicher Schritt in dieser Entwicklung.
Ich denke manchmal, dass es ein guter Marketingtrick wäre, ihn als verbesserte Version von Python zu bezeichnen. Das klingt hipper als Lisp. Für viele Leute ist Lisp eine langsame KI-Sprache mit vielen Klammern. Fritz Kunzes offizielle Biografie vermeidet sorgfältig die Erwähnung des L-Wortes. Aber ich vermute, wir sollten keine Angst haben, den neuen Lisp Lisp zu nennen. Lisp hat immer noch viel latentes Ansehen bei den allerbesten Hackern – denen, die 6.001 gemacht und verstanden haben, zum Beispiel. Und das sind die Benutzer, die Sie gewinnen müssen.
In „How to Become a Hacker“ beschreibt Eric Raymond Lisp als etwas wie Latein oder Griechisch – eine Sprache, die man als intellektuelle Übung lernen sollte, auch wenn man sie nicht tatsächlich benutzt:
Lisp ist es wert, für die tiefgreifende Erleuchtungserfahrung gelernt zu werden, die man haben wird, wenn man es endlich versteht; diese Erfahrung wird Sie für den Rest Ihrer Tage zu einem besseren Programmierer machen, auch wenn Sie Lisp selbst nie viel benutzen.
Wenn ich Lisp nicht kennen würde, würde mich das Lesen dazu bringen, Fragen zu stellen. Eine Sprache, die mich zu einem besseren Programmierer machen würde, bedeutet, wenn sie überhaupt etwas bedeutet, eine Sprache, die besser zum Programmieren wäre. Und das ist tatsächlich die Implikation dessen, was Eric sagt.
Solange diese Idee noch im Umlauf ist, denke ich, werden Hacker einem neuen Lisp gegenüber aufgeschlossen genug sein, auch wenn er Lisp genannt wird. Aber dieser Lisp muss eine Hacker-Sprache sein, wie die klassischen Lisps der 1970er Jahre. Er muss kurz, einfach und hackbar sein. Und er muss mächtige Bibliotheken haben, um das zu tun, was Hacker heute wollen.
Bei den Bibliotheken denke ich, dass es Raum gibt, Sprachen wie Perl und Python in ihrem eigenen Spiel zu schlagen. Viele der neuen Anwendungen, die in den kommenden Jahren geschrieben werden müssen, werden serverbasierte Anwendungen sein. Es gibt keinen Grund, warum ein neuer Lisp keine Zeichenkettenbibliotheken haben sollte, die so gut sind wie die von Perl, und wenn dieser neue Lisp auch mächtige Bibliotheken für serverbasierte Anwendungen hätte, könnte er sehr populär werden. Echte Hacker werden eine neue Werkzeug nicht verachten, das es ihnen ermöglicht, schwierige Probleme mit wenigen Bibliotheksaufrufen zu lösen. Denken Sie daran, Hacker sind faul.
Es könnte ein noch größerer Gewinn sein, Kernsprachenunterstützung für serverbasierte Anwendungen zu haben. Zum Beispiel explizite Unterstützung für Programme mit mehreren Benutzern oder Datenbesitz auf Ebene von Typ-Tags.
Serverbasierte Anwendungen geben uns auch die Antwort auf die Frage, wozu dieser neue Lisp verwendet werden soll. Es würde nicht schaden, Lisp als Skriptsprache für Unix besser zu machen. (Es wäre schwer, es schlechter zu machen.) Aber ich denke, es gibt Bereiche, in denen bestehende Sprachen leichter zu schlagen wären. Ich denke, es wäre besser, dem Modell von Tcl zu folgen und Lisp zusammen mit einem vollständigen System zur Unterstützung serverbasierter Anwendungen bereitzustellen. Lisp ist eine natürliche Ergänzung für serverbasierte Anwendungen. Lexikalische Closures bieten eine Möglichkeit, den Effekt von Subroutinen zu erzielen, wenn die Benutzeroberfläche nur eine Reihe von Webseiten ist. S-Ausdrücke lassen sich gut auf HTML abbilden, und Makros sind gut darin, es zu generieren. Es werden bessere Werkzeuge zum Schreiben serverbasierter Anwendungen benötigt, und es wird ein neuer Lisp benötigt, und die beiden würden sehr gut zusammenarbeiten.
12 Die Traum-Sprache
Zusammenfassend lässt sich sagen, dass wir versuchen, die Traum-Sprache des Hackers zu beschreiben. Die Traum-Sprache ist schön, sauber und kurz. Sie hat eine interaktive Top-Level-Umgebung, die schnell startet. Sie können Programme schreiben, um häufige Probleme mit sehr wenig Code zu lösen. Fast der gesamte Code in jedem Programm, das Sie schreiben, ist Code, der spezifisch für Ihre Anwendung ist. Alles andere wurde für Sie erledigt.
Die Syntax der Sprache ist bis zum Übermaß kurz. Sie müssen nie ein unnötiges Zeichen tippen oder gar die Umschalttaste viel benutzen.
Mit großen Abstraktionen können Sie die erste Version eines Programms sehr schnell schreiben. Später, wenn Sie optimieren möchten, gibt es einen wirklich guten Profiler, der Ihnen sagt, worauf Sie Ihre Aufmerksamkeit richten sollen. Sie können innere Schleifen blendend schnell machen, sogar Inline-Bytecode schreiben, wenn Sie ihn brauchen.
Es gibt viele gute Beispiele zum Lernen, und die Sprache ist intuitiv genug, dass Sie in ein paar Minuten lernen können, wie man sie benutzt. Sie müssen das Handbuch nicht oft nachschlagen. Das Handbuch ist dünn und enthält wenige Warnungen und Einschränkungen.
Die Sprache hat einen kleinen Kern und mächtige, hochgradig orthogonale Bibliotheken, die genauso sorgfältig entworfen sind wie die Kernsprache. Die Bibliotheken arbeiten alle gut zusammen; alles in der Sprache passt zusammen wie die Teile einer feinen Kamera. Nichts ist veraltet oder aus Kompatibilitätsgründen beibehalten. Der Quellcode aller Bibliotheken ist leicht verfügbar. Es ist einfach, mit dem Betriebssystem und mit Anwendungen zu sprechen, die in anderen Sprachen geschrieben sind.
Die Sprache ist in Schichten aufgebaut. Die höherstufigen Abstraktionen sind auf sehr transparente Weise aus niedrigerstufigen Abstraktionen aufgebaut, die Sie erhalten können, wenn Sie möchten.
Nichts ist Ihnen verborgen, was nicht unbedingt verborgen sein muss. Die Sprache bietet Abstraktionen nur als Mittel zur Arbeitsersparnis an, anstatt als Mittel, Ihnen zu sagen, was Sie tun sollen. Tatsächlich ermutigt die Sprache Sie, ein gleichberechtigter Teilnehmer an ihrem Design zu sein. Sie können alles daran ändern, einschließlich sogar ihrer Syntax, und alles, was Sie schreiben, hat so weit wie möglich den gleichen Status wie das, was vordefiniert ist.
Anmerkungen
[1] Makros, die der modernen Idee sehr nahe kamen, wurden 1964 von Timothy Hart vorgeschlagen, zwei Jahre nach der Veröffentlichung von Lisp 1.5. Was anfangs fehlte, waren Wege, Variablenerfassung und mehrfache Auswertung zu vermeiden; Hart's Beispiele unterliegen beidem.
[2] In When the Air Hits Your Brain erzählt der Neurochirurg Frank Vertosick ein Gespräch, in dem sein leitender Assistenzarzt Gary über den Unterschied zwischen Chirurgen und Internisten („Flöhe“) spricht:
Gary und ich bestellten eine große Pizza und fanden eine freie Nische. Der Chef zündete sich eine Zigarette an. „Schau dir diese verdammten Flöhe an, die über eine Krankheit schwadronieren, die sie einmal in ihrem Leben sehen. Das ist das Problem mit Flöhen, sie mögen nur das Bizarre. Sie hassen ihre täglichen Fälle. Das ist der Unterschied zwischen uns und den verdammten Flöhen. Siehst du, wir lieben große, saftige Bandscheibenvorfälle, aber sie hassen Bluthochdruck…“
Es ist schwer, einen Bandscheibenvorfall als saftig zu bezeichnen (außer wörtlich). Und doch glaube ich, ich weiß, was sie meinen. Ich hatte oft einen saftigen Bug zu verfolgen. Jemand, der kein Programmierer ist, würde es schwer finden, sich vorzustellen, dass ein Bug Vergnügen bereiten könnte. Sicherlich ist es besser, wenn alles einfach funktioniert. In gewisser Weise ist es das. Und doch gibt es unbestreitbar eine düstere Befriedigung, bestimmte Arten von Fehlern zu jagen.