BELIEBT SEIN
OriginalMai 2001
(Dieser Artikel wurde als eine Art Geschäftsplan für eine neue Sprache geschrieben. Daher fehlt ihm (weil er es als selbstverständlich voraussetzt) das wichtigste Merkmal einer guten Programmiersprache: sehr leistungsfähige Abstraktionen.)
Einer meiner Freunde erzählte einmal einem namhaften Betriebssystemexperten, er wolle eine wirklich gute Programmiersprache entwickeln. Der Experte sagte ihm, das wäre reine Zeitverschwendung, denn Programmiersprachen würden weder aufgrund ihrer Vorzüge populär noch unbeliebt, und egal, wie gut seine Sprache sei, niemand würde sie verwenden. Zumindest war das mit der Sprache passiert, die er entwickelt hatte.
Was macht eine Sprache populär? Verdienen populäre Sprachen ihre Popularität? Lohnt es sich, eine gute Programmiersprache zu definieren? Wie würden Sie das tun?
Ich denke, die Antworten auf diese Fragen können gefunden werden, indem man sich Hacker ansieht und herausfindet, was sie wollen. Programmiersprachen sind für Hacker, und eine Programmiersprache ist als Programmiersprache gut (und nicht etwa als Übung in denotationaler Semantik oder Compilerdesign), wenn und nur wenn sie Hackern gefällt.
1 Die Mechanismen der Popularität
Es stimmt natürlich, dass die meisten Leute Programmiersprachen nicht einfach aufgrund ihrer Vorzüge auswählen. Den meisten Programmierern wird von jemand anderem gesagt, welche Sprache sie verwenden sollen. Und dennoch 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 mit der der meisten Sprachentwickler übereinstimmt.
Von beidem ist die Meinung des Hackers diejenige, die zählt. Programmiersprachen sind keine Theoreme. Sie sind Werkzeuge, die für Menschen entwickelt wurden, und sie müssen so entwickelt werden, dass sie den menschlichen Stärken und Schwächen entsprechen, so wie Schuhe für menschliche Füße entwickelt werden müssen. Wenn ein Schuh beim Anziehen drückt, ist er ein schlechter Schuh, wie elegant er als Skulptur auch sein mag.
Es mag sein, dass die Mehrheit der Programmierer eine gute Sprache nicht von einer schlechten unterscheiden kann. Aber das ist bei keinem anderen Werkzeug anders. Das heißt nicht, dass es Zeitverschwendung ist, eine gute Sprache zu entwickeln. Erfahrene Hacker erkennen eine gute Sprache, wenn sie eine sehen, und sie werden sie verwenden. Erfahrene Hacker sind zugegebenermaßen eine winzige Minderheit, aber diese winzige Minderheit schreibt die ganze gute Software, und ihr Einfluss ist so groß, dass die übrigen Programmierer dazu neigen, dieselbe Sprache zu verwenden, die sie verwenden. Tatsächlich geht es oft nicht nur um Einfluss, sondern um Befehlsgewalt: Oft sind es die erfahrenen Hacker, die als ihre Chefs oder Fakultätsberater den anderen Programmierern sagen, welche Sprache sie verwenden sollen.
Die Meinung von erfahrenen Hackern ist nicht die einzige Kraft, die die relative Popularität von Programmiersprachen bestimmt – auch veraltete Software (Cobol) und Hype (Ada, Java) spielen eine Rolle – aber ich denke, dass sie auf lange Sicht die stärkste Kraft ist. Mit einer anfänglichen kritischen Masse und genügend Zeit wird eine Programmiersprache wahrscheinlich ungefähr so populär, wie sie es verdient. Und Popularität unterscheidet gute Sprachen noch weiter von schlechten, denn Feedback von echten Benutzern führt immer zu Verbesserungen. Sehen Sie sich an, wie sehr sich eine populäre Sprache im Laufe ihres Lebens verändert hat. Perl und Fortran sind Extremfä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 einige Jahre damit verbracht hatten, mit Lisp echte Programme zu schreiben. [1]
Unabhängig davon, ob eine Sprache gut sein muss, um populär zu sein, denke ich, dass eine Sprache populär sein muss, um gut zu sein. Und sie muss populär bleiben, um gut zu bleiben. Der Stand der Technik bei Programmiersprachen steht nicht still. Und doch sind die Lisps, die wir heute haben, immer noch ziemlich genau das, was sie Mitte der 1980er Jahre am MIT hatten, denn das war das letzte Mal, dass Lisp eine ausreichend große und anspruchsvolle Benutzerbasis hatte.
Natürlich müssen Hacker eine Sprache kennen, bevor sie sie verwenden können. Wie sollen sie davon erfahren? Von anderen Hackern. Aber es muss eine anfängliche Gruppe von Hackern geben, die die Sprache verwenden, damit andere überhaupt davon erfahren. Ich frage mich, wie groß diese Gruppe sein muss; wie viele Benutzer bilden eine kritische Masse? Spontan würde ich sagen, zwanzig. Wenn eine Sprache zwanzig verschiedene Benutzer hätte, also zwanzig Benutzer, die sich von sich aus entschieden haben, sie zu verwenden, würde ich sie als real betrachten.
Das zu erreichen, dürfte 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 ersten zwanzig Benutzer zu gewinnen, ist wahrscheinlich der Einsatz 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 mit der Feststellung, dass ein externer Faktor 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 der frühen IBM-Mainframes. 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 gedacht.
Lisp ist keine extrem populäre Sprache, weil es nicht die Skriptsprache eines extrem populären Systems ist. Die Popularität, die es noch hat, geht auf die 1960er und 1970er Jahre zurück, als es die Skriptsprache des MIT war. Viele der großen Programmierer der damaligen Zeit waren irgendwann einmal mit dem MIT verbunden. Und in den frühen 1970er Jahren, vor C, war der Lisp-Dialekt des MIT, MacLisp, eine der wenigen Programmiersprachen, die ein ernsthafter Hacker verwenden wollte.
Heute ist Lisp die Skriptsprache zweier mäßig populärer Systeme, 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. Hacken ist ein transitives Verb – Hacker hacken normalerweise etwas – und in der Praxis werden Sprachen im Verhältnis zu dem beurteilt, was sie zum Hacken verwenden. Wenn Sie also eine populäre Sprache entwickeln möchten, müssen Sie entweder mehr als eine Sprache bereitstellen oder Ihre Sprache so entwickeln, dass sie die Skriptsprache eines vorhandenen Systems ersetzt.
Common Lisp ist teilweise deshalb unbeliebt, weil es ein Waisenkind ist. Ursprünglich war es mit einem System zum Hacken ausgestattet: der Lisp-Maschine. Aber Lisp-Maschinen (zusammen mit Parallelrechnern) wurden in den 1980er Jahren durch die zunehmende Leistungsfähigkeit von Allzweckprozessoren überrollt. Common Lisp wäre möglicherweise weiterhin beliebt, wenn es eine gute Skriptsprache für Unix gewesen wäre. Leider ist es eine schrecklich schlechte.
Diese Situation lässt sich folgendermaßen beschreiben: Eine Sprache wird nicht nach ihren eigenen Vorzügen beurteilt. Eine andere Ansicht ist, dass eine Programmiersprache keine richtige Programmiersprache ist, wenn sie nicht gleichzeitig auch die Skriptsprache für etwas ist. Das erscheint nur dann unfair, wenn es überraschend kommt. Ich denke, es ist nicht unfairer, als zu erwarten, dass eine Programmiersprache beispielsweise eine Implementierung hat. Das ist einfach ein Teil dessen, was eine Programmiersprache ist.
Eine Programmiersprache braucht natürlich eine gute Implementierung, und diese muss kostenlos sein. Unternehmen zahlen für Software, aber einzelne Hacker nicht, und genau diese Hacker müssen Sie anlocken.
Zu einer Sprache muss es auch ein Buch geben. 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 es zu einer Sprache ein Buch bei O'Reilly geben muss. Das wird für Hacker zum Maßstab, ob sie wichtig sind.
Es sollte auch Online-Dokumentation geben. Tatsächlich kann das Buch als Online-Dokumentation beginnen. Aber ich glaube nicht, dass gedruckte Bücher schon veraltet sind. Ihr Format ist praktisch und die von den Verlegern auferlegte De-facto-Zensur ist ein nützlicher, wenn auch unvollkommener Filter. Buchhandlungen sind einer der wichtigsten Orte, um neue Sprachen zu lernen.
3 Kürze
Vorausgesetzt, Sie können die drei Dinge bereitstellen, die jede Sprache benötigt – eine kostenlose Implementierung, ein Buch und etwas zum Hacken –, wie erstellen Sie eine Sprache, die Hackern gefällt?
Hacker mögen Kürze. Hacker sind faul, genau wie Mathematiker und moderne Architekten: Sie hassen alles Überflüssige. Es wäre nicht weit von der Wahrheit entfernt zu sagen, dass ein Hacker, der gerade ein Programm schreibt, zumindest unbewusst entscheidet, welche Sprache er verwendet, basierend auf der Gesamtzahl der Zeichen, die er eingeben muss. Wenn Hacker nicht genau so denken, wäre ein Sprachentwickler gut beraten, so zu handeln, als ob es so wäre.
Es ist ein Fehler, den Benutzer mit langatmigen Ausdrücken zu verhätscheln, die Englisch ähneln sollen. Cobol ist für diesen Fehler berüchtigt. Ein Hacker würde es in Betracht ziehen, gebeten zu werden,
addiere x zu y, ergibt z
anstatt
z = x+y
als etwas zwischen einer Beleidigung seiner Intelligenz und einer Sünde gegen Gott.
Es wurde manchmal gesagt, dass Lisp „first“ und „rest“ statt „car“ und „cdr“ verwenden sollte, weil dies die 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 und „cdr“ den Rest bedeutet. Die Verwendung von „first“ und „rest“ bedeutet 50 % mehr Tipparbeit. Und sie haben auch unterschiedliche Längen, was bedeutet, dass die Argumente nicht in einer Reihe angeordnet sind, wenn sie aufgerufen werden, wie es bei „car“ und „cdr“ oft der Fall ist, und zwar in aufeinanderfolgenden Zeilen. Ich habe festgestellt, dass es sehr wichtig ist, wie Code auf der Seite angeordnet ist. 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 Punkt, bei dem stark typisierte Sprachen verlieren. Wenn alle anderen Dinge gleich sind, möchte niemand ein Programm mit einer Menge Deklarationen beginnen. Alles, was implizit sein kann, sollte es auch sein.
Auch die einzelnen Token sollten kurz sein. Perl und Common Lisp stehen in dieser Frage entgegengesetzten Positionen gegenüber. Perl-Programme können fast kryptisch dicht sein, während die Namen der integrierten Common Lisp-Operatoren geradezu lächerlich lang sind. Die Entwickler von Common Lisp erwarteten wahrscheinlich, dass Benutzer Texteditoren haben, die diese langen Namen für sie eingeben. Aber die Kosten eines langen Namens bestehen nicht nur darin, ihn einzugeben. Es gibt auch die Kosten für das Lesen und den Platz, den er auf Ihrem Bildschirm einnimmt.
4 Hackbarkeit
Für einen Hacker ist etwas wichtiger als Kürze: zu können, was man will. In der Geschichte der Programmiersprachen wurde überraschend viel Aufwand betrieben, um Programmierer davon abzuhalten, Dinge zu tun, die als unzulässig angesehen werden. Dies ist ein gefährlich anmaßender Plan. Woher soll der Sprachentwickler wissen, was der Programmierer tun muss? Ich denke, Sprachentwickler sollten ihren Zielbenutzer besser als Genie betrachten, das Dinge tun muss, die es nie erwartet hätte, und nicht als Stümper, der vor sich selbst geschützt werden muss. Der Stümper schießt sich sowieso selbst ins Bein. Sie können ihn vielleicht davor bewahren, auf Variablen in einem anderen Paket zu verweisen, aber Sie können ihn nicht davor bewahren, ein schlecht konzipiertes Programm zu schreiben, um das falsche Problem zu lösen, und dafür ewig zu brauchen.
Gute Programmierer wollen oft gefährliche und unappetitliche Dinge tun. Mit unappetitlich meine ich Dinge, die hinter der semantischen Fassade liegen, die die Sprache zu präsentieren versucht: sich beispielsweise die interne Darstellung einer abstrakten Ebene zu verschaffen. Hacker hacken gern, und Hacken bedeutet, in die Dinge einzudringen und den ursprünglichen Designer zu hinterfragen.
Lassen Sie sich nicht hinterfragen. Wenn Sie ein Tool erstellen, verwenden die Leute es auf eine Art und Weise, die Sie nicht beabsichtigt haben. Dies gilt insbesondere für ein hochartikuliertes Tool wie eine Programmiersprache. Viele Hacker werden Ihr semantisches Modell auf eine Art und Weise optimieren wollen, die Sie sich nie hätten vorstellen können. Ich sage: Lassen Sie sie; geben Sie dem Programmierer Zugriff auf so viele interne Dinge wie möglich, ohne Laufzeitsysteme wie den Garbage Collector zu gefährden.
In Common Lisp wollte ich oft durch die Felder einer Struktur iterieren – um beispielsweise Verweise auf ein gelöschtes Objekt herauszufiltern oder nicht initialisierte Felder zu finden. Ich weiß, dass die Strukturen im Grunde nur Vektoren sind. Und dennoch kann ich keine Allzweckfunktion schreiben, die ich für jede Struktur aufrufen kann. Ich kann nur über den Namen auf die Felder zugreifen, denn das ist die Bedeutung einer Struktur.
Ein Hacker möchte vielleicht nur ein- oder zweimal in einem großen Programm das beabsichtigte Modell der Dinge untergraben. Aber es macht einen großen Unterschied, wenn man dazu in der Lage ist. Und es kann mehr sein als nur die Lösung eines Problems. Es geht auch um eine Art Vergnügen. Hacker teilen das heimliche Vergnügen des Chirurgen, in ekligen Innereien herumzustochern, das heimliche Vergnügen des Teenagers, Pickel auszudrücken. [2] Zumindest für Jungen sind bestimmte Arten von Horror faszinierend. Das Maxim-Magazin veröffentlicht jedes Jahr einen Fotoband, der eine Mischung aus Pin-ups und grausigen Unfällen enthält. Sie kennen ihr Publikum.
Historisch gesehen war Lisp gut darin, Hackern ihren Willen zu lassen. Die politische Korrektheit von Common Lisp ist eine Anomalie. Mit den frühen Lisps konnte man alles in die Finger kriegen. Ein Großteil dieses Geistes ist glücklicherweise in Makros erhalten geblieben. Es ist eine wunderbare Sache, beliebige Transformationen am Quellcode vornehmen zu können.
Klassische Makros sind ein echtes Hacker-Tool – einfach, leistungsstark 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 gegenteilige Prinzip. Sie versuchen, Sie davor zu schützen, zu verstehen, 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, die entstehen, wenn man entscheidet, 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 gestaltet, mit einem kleinen Kern gut verstandener und hochgradig orthogonaler Operatoren, aber schmutzig in dem Sinne, dass Hacker damit machen können, was sie wollen. C ist so. Das galt auch für die frühen Lisps. Eine echte Hackersprache wird immer einen leicht verlotterten Charakter haben.
Eine gute Programmiersprache sollte Eigenschaften haben, die Leute, die den Begriff „Software-Engineering“ verwenden, missbilligend den Kopf schütteln lassen. Am anderen Ende des Spektrums stehen Sprachen wie Ada und Pascal, Modelle der Angemessenheit, die sich gut zum Unterrichten eignen, aber sonst nicht viel.
5 Wegwerfprogramme
Um für Hacker attraktiv zu sein, muss eine Sprache gut für das Schreiben der Programme sein, die sie schreiben wollen. Und das bedeutet, vielleicht überraschend, dass sie gut für das Schreiben von Wegwerfprogrammen sein muss.
Ein Wegwerfprogramm ist ein Programm, das Sie schnell für eine begrenzte Aufgabe schreiben: ein Programm zur Automatisierung einer Systemadministrationsaufgabe, zum Generieren von Testdaten für eine Simulation oder zum Konvertieren von Daten von einem Format in ein anderes. Das Überraschende an Wegwerfprogrammen ist, dass sie, wie die „provisorischen“ Gebäude, die während des Zweiten Weltkriegs an so vielen amerikanischen Universitäten gebaut wurden, oft nicht weggeworfen werden. Viele entwickeln sich zu echten Programmen mit echten Funktionen und echten Benutzern.
Ich habe das Gefühl, dass die besten großen Projekte auf diese Weise beginnen, anstatt wie der Hoover-Staudamm von Anfang an groß angelegt zu sein. Es ist furchterregend, etwas Großes aus dem Nichts zu bauen. Wenn Leute ein zu großes Projekt in Angriff nehmen, sind sie überfordert. Entweder kommt das Projekt ins Stocken, oder das Ergebnis ist steril und hölzern: ein Einkaufszentrum statt einer echten Innenstadt, Brasilia statt Rom, Ada statt C.
Eine andere Möglichkeit, ein großes Programm zu erhalten, besteht darin, mit einem Wegwerfprogramm zu beginnen und es ständig zu verbessern. Dieser Ansatz ist weniger entmutigend und das Design des Programms profitiert von der Entwicklung. Ich denke, wenn man sich das ansieht, würde sich herausstellen, dass dies die Art und Weise ist, wie die meisten großen Programme entwickelt wurden. Und diejenigen, die sich auf diese Weise entwickelt haben, sind wahrscheinlich immer noch in der Sprache geschrieben, in der sie ursprünglich geschrieben wurden, weil es selten vorkommt, dass ein Programm portiert wird, außer aus politischen Gründen. Paradoxerweise muss man also, wenn man eine Sprache für große Systeme entwickeln möchte, sie für das Schreiben von Wegwerfprogrammen gut machen, denn das ist der Ursprung großer Systeme.
Perl ist ein eindrucksvolles Beispiel für diese Idee. Es wurde nicht nur zum Schreiben von Wegwerfprogrammen entwickelt, sondern war selbst so ziemlich ein Wegwerfprogramm. Perl begann als Sammlung von Dienstprogrammen zum Generieren von Berichten und entwickelte sich erst zu einer Programmiersprache, als die Zahl der Wegwerfprogramme, die man darin schrieb, immer größer wurde. Erst mit Perl 5 (wenn überhaupt) war die Sprache zum Schreiben ernsthafter Programme geeignet, und dennoch war sie bereits enorm beliebt.
Was macht eine Sprache für Wegwerfprogramme geeignet? Zunächst einmal muss sie leicht verfügbar sein. Ein Wegwerfprogramm ist etwas, das Sie voraussichtlich in einer Stunde schreiben. Die Sprache muss also wahrscheinlich bereits auf dem Computer installiert sein, den Sie verwenden. Sie kann nicht etwas sein, das Sie installieren müssen, bevor Sie es verwenden. Sie muss da sein. C war da, weil es mit dem Betriebssystem geliefert wurde. Perl war da, weil es ursprünglich ein Tool für Systemadministratoren war und Ihr Computer es bereits installiert hatte.
Verfügbarkeit bedeutet allerdings mehr als nur installiert zu sein. Eine interaktive Sprache mit einer Befehlszeilenschnittstelle ist verfügbarer als eine, die Sie separat kompilieren und ausführen müssen. Eine beliebte Programmiersprache sollte interaktiv sein und schnell starten.
Ein weiteres wichtiges Merkmal eines Wegwerfprogramms ist Kürze. Kürze ist für Hacker immer attraktiv, und das gilt besonders für Programme, die sie in einer Stunde fertigstellen wollen.
6 Bibliotheken
Das kürzeste Programm ist natürlich, wenn das Programm bereits für Sie geschrieben ist und Sie es nur noch aufrufen müssen. Und das bringt uns zu einem meiner Meinung nach immer wichtiger werdenden Merkmal von Programmiersprachen: Bibliotheksfunktionen. Perl gewinnt, weil es große Bibliotheken zur Manipulation von Zeichenfolgen hat. Diese Klasse von Bibliotheksfunktionen ist besonders wichtig für Wegwerfprogramme, die oft ursprünglich zum Konvertieren oder Extrahieren von Daten geschrieben werden. Viele Perl-Programme beginnen wahrscheinlich nur mit ein paar zusammengefügten Bibliotheksaufrufen.
Ich denke, dass viele der Fortschritte, die in den nächsten fünfzig Jahren bei Programmiersprachen gemacht werden, mit Bibliotheksfunktionen zu tun haben werden. Ich denke, dass zukünftige Programmiersprachen Bibliotheken haben werden, die genauso sorgfältig entworfen werden wie die Kernsprache. Beim Entwurf von Programmiersprachen wird es nicht darum gehen, ob man seine Sprache stark oder schwach typisiert, objektorientiert, funktional oder was auch immer machen soll, sondern darum, wie man großartige Bibliotheken entwirft. Die Art von Sprachdesignern, die gerne darüber nachdenken, wie man Typsysteme entwirft, werden bei dieser Vorstellung vielleicht erschaudern. Es ist fast wie das Schreiben von Anwendungen! Schade. Sprachen sind für Programmierer, und Bibliotheken sind das, was Programmierer brauchen.
Es ist schwierig, gute Bibliotheken zu entwerfen. Es geht nicht einfach darum, viel Code zu schreiben. Wenn 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 einer kleinen Anzahl orthogonaler Operatoren entworfen werden, genau wie die Kernsprache. Der Programmierer sollte erraten können, welcher Bibliotheksaufruf das bewirkt, was er braucht.
Bei den Bibliotheken schwächelt Common Lisp. Es gibt nur rudimentäre Bibliotheken zur Manipulation von Strings und fast keine zur Kommunikation mit dem Betriebssystem. Aus historischen Gründen versucht Common Lisp so zu tun, als ob das Betriebssystem nicht existiere. Und weil Sie nicht mit dem Betriebssystem kommunizieren können, ist es unwahrscheinlich, dass Sie ein ernsthaftes Programm schreiben können, indem Sie nur die integrierten Operatoren von Common Lisp verwenden. Sie müssen auch einige implementierungsspezifische Hacks verwenden, und in der Praxis bieten diese Ihnen meist nicht alles, was Sie wollen. Hacker würden Lisp viel mehr schätzen, wenn Common Lisp über leistungsstarke String-Bibliotheken und gute Betriebssystemunterstützung verfügen würde.
7 Syntax
Könnte eine Sprache mit der Syntax von Lisp, oder genauer gesagt, dem Fehlen einer Syntax, jemals populär werden? Ich kenne die Antwort auf diese Frage nicht. Ich glaube allerdings, dass die Syntax nicht der Hauptgrund dafür ist, dass Lisp derzeit nicht populär ist. Common Lisp hat schlimmere Probleme als eine unbekannte Syntax. Ich kenne mehrere Programmierer, die mit der Präfixsyntax vertraut sind und dennoch standardmäßig Perl verwenden, weil es über leistungsstarke String-Bibliotheken verfügt und mit dem Betriebssystem kommunizieren kann.
Es gibt zwei mögliche Probleme mit der Präfixnotation: Sie ist Programmierern unbekannt und sie ist nicht dicht genug. In der Lisp-Welt ist man sich allgemein einig, dass das erste Problem das eigentliche ist. Ich bin mir da nicht so sicher. Ja, Präfixnotation versetzt normale Programmierer in Panik. Aber ich glaube nicht, dass die Meinung normaler Programmierer wichtig ist. Sprachen werden beliebt oder unbeliebt, je nachdem, was erfahrene Hacker von ihnen halten, und ich glaube, erfahrene Hacker könnten mit der Präfixnotation zurechtkommen. Die Perl-Syntax kann ziemlich unverständlich sein, aber das hat der Popularität von Perl keinen Abbruch getan. Wenn überhaupt, hat es vielleicht zur Entstehung eines Perl-Kults beigetragen.
Ein ernsteres Problem ist die Undurchsichtigkeit der Präfixnotation. Für erfahrene Hacker ist das wirklich ein Problem. Niemand möchte (aref axy) schreiben, wenn er a[x,y] schreiben könnte.
In diesem speziellen Fall gibt es eine Möglichkeit, das Problem zu lösen. Wenn wir Datenstrukturen so behandeln, als wären sie Funktionen auf Indizes, könnten wir stattdessen (axy) schreiben, was sogar 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 Einrückungen als signifikant betrachten. So lesen Programmierer Code ohnehin: Wenn Einrückungen etwas anderes aussagen als Trennzeichen, richten wir uns nach den Einrückungen. Wenn wir Einrückungen als signifikant betrachten, können wir diese häufige Fehlerquelle beseitigen und gleichzeitig Programme kürzer machen.
Manchmal ist die Infix-Syntax leichter zu lesen. Das gilt insbesondere für mathematische Ausdrücke. Ich habe mein ganzes Programmierleben lang Lisp verwendet und finde mathematische Ausdrücke mit Präfixen immer noch nicht natürlich. Und dennoch ist es praktisch, Operatoren zu haben, die eine beliebige Anzahl von Argumenten annehmen, insbesondere wenn Sie Code generieren. Wenn wir also eine Infix-Syntax haben, sollte diese wahrscheinlich als eine Art Lese-Makro implementiert werden.
Ich denke nicht, dass wir uns grundsätzlich gegen die Einführung von Syntax in Lisp wehren sollten, solange sie sich auf verständliche Weise in zugrunde liegende S-Ausdrücke übersetzen lässt. Lisp hat bereits eine Menge Syntax. Es ist nicht unbedingt schlecht, mehr davon einzuführen, solange niemand gezwungen wird, es zu verwenden. In Common Lisp sind einige Trennzeichen für die Sprache reserviert, was darauf schließen lässt, dass zumindest einige der Entwickler beabsichtigten, in Zukunft mehr Syntax einzubauen.
Einer der am meisten unlispy Syntaxbestandteile in Common Lisp kommt in Formatzeichenfolgen vor; Format ist eine eigenständige Sprache, und diese Sprache ist nicht Lisp. Wenn es Pläne gäbe, mehr Syntax in Lisp einzuführen, könnten Formatbezeichner darin enthalten sein. Es wäre gut, wenn Makros Formatbezeichner so generieren könnten, wie sie jede andere Art von Code generieren.
Ein bekannter Lisp-Hacker hat mir gesagt, dass seine Kopie von CLTL auf das Abschnittsformat aufspringt. Meine auch. Das deutet wahrscheinlich auf Verbesserungsbedarf hin. Es kann auch bedeuten, dass Programme viel I/O durchführen.
8 Effizienz
Wie jeder weiß, sollte eine gute Sprache schnellen Code erzeugen. In der Praxis glaube ich jedoch nicht, dass schneller Code in erster Linie durch Dinge entsteht, die man beim Entwurf der Sprache tut. Wie Knuth schon vor langer Zeit betonte, ist Geschwindigkeit nur bei bestimmten kritischen Engpässen wichtig. Und wie viele Programmierer seitdem festgestellt haben, irrt man sich sehr oft darüber, wo diese Engpässe liegen.
In der Praxis ist also ein sehr guter Profiler die beste Methode, um Code zu beschleunigen, und nicht etwa eine stark typisierte Sprache. Sie müssen nicht den Typ jedes Arguments in jedem Aufruf des Programms kennen. Sie müssen in der Lage sein, die Typen der Argumente in den Engpässen zu deklarieren. Und noch wichtiger: Sie müssen herausfinden können, wo die Engpässe sind.
Eine Beschwerde, die Leute über Lisp hatten, ist, dass es schwer ist zu sagen, was teuer ist. Das könnte stimmen. Es könnte auch unvermeidlich sein, wenn Sie eine sehr abstrakte Sprache haben möchten. Und auf jeden Fall denke ich, dass eine gute Profilierung viel dazu beitragen würde, das Problem zu lösen: Sie würden bald lernen, was teuer ist.
Ein Teil des Problems ist hier sozialer Natur. Sprachentwickler schreiben gern schnelle Compiler. Daran messen sie ihre Fähigkeiten. Sie betrachten den Profiler bestenfalls als Zusatz. In der Praxis kann ein guter Profiler jedoch mehr zur Geschwindigkeit tatsächlich in der Sprache geschriebener Programme beitragen als ein Compiler, der schnellen Code generiert. Auch hier haben Sprachentwickler den Kontakt zu ihren Benutzern ein wenig verloren. Sie lösen wirklich gut das leicht falsche Problem.
Es könnte eine gute Idee sein, einen aktiven Profiler zu haben, um Leistungsdaten an den Programmierer zu senden, anstatt darauf zu warten, dass er danach fragt. Beispielsweise 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 insbesondere bei serverbasierten Anwendungen von großem Vorteil, bei denen Sie viele laufende Programme im Auge behalten müssen. Ein aktiver Profiler könnte grafisch darstellen, was während der Ausführung eines Programms im Speicher passiert, oder sogar Töne erzeugen, die verraten, was passiert.
Geräusche sind ein guter Hinweis auf Probleme. An einem meiner Arbeitsplätze hatten wir eine große Anzeigetafel, auf der angezeigt wurde, was mit unseren Webservern passierte. Die Zeiger wurden von kleinen Servomotoren bewegt, die beim Drehen ein leises Geräusch machten. Von meinem Schreibtisch aus konnte ich die Anzeigetafel nicht sehen, aber ich stellte fest, dass ich sofort am Geräusch erkennen konnte, wenn 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 traurige Geschichte über seinen Job als Bundesbeamter zu erzählen. Ich habe oft das Gefühl, dass ich den Prozessor auf eine Menge sinnloser Verfolgungsjagden schicke, aber ich hatte nie eine gute Möglichkeit, zu sehen, was er tut.
Einige Lisps werden jetzt in Bytecode kompiliert, der dann von einem Interpreter ausgeführt wird. Dies wird normalerweise gemacht, um die Portierbarkeit der Implementierung zu erleichtern, könnte aber auch ein nützliches Sprachfeature sein. Es wäre vielleicht eine gute Idee, den Bytecode zu einem offiziellen Teil der Sprache zu machen und Programmierern zu erlauben, Inline-Bytecode in Engpässen zu verwenden. Dann wären solche Optimierungen auch portierbar.
Die Art der Geschwindigkeit, wie sie vom Endbenutzer wahrgenommen wird, kann sich ändern. Mit dem Aufkommen serverbasierter Anwendungen können sich immer mehr Programme als I/O-gebunden erweisen. Es wird sich lohnen, I/O schnell zu machen. Die Sprache kann mit einfachen Maßnahmen wie einfachen, schnellen, formatierten Ausgabefunktionen und auch mit tiefgreifenden strukturellen Änderungen wie Caching und persistenten Objekten helfen.
Benutzer sind an der Reaktionszeit interessiert. Aber eine andere Art der Effizienz wird zunehmend wichtiger: die Anzahl gleichzeitiger 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 entscheidende Frage für jeden, der solche Anwendungen hostet. Bei den Kapitalkosten eines Unternehmens, das eine serverbasierte Anwendung anbietet, ist dies der Divisor.
Jahrelang spielte Effizienz bei den meisten Endbenutzeranwendungen keine große Rolle. Entwickler konnten davon ausgehen, dass jeder Benutzer einen immer leistungsstärkeren Prozessor auf seinem Schreibtisch stehen hatte. Und nach Parkinsons Gesetz hat sich die Software so erweitert, dass sie die verfügbaren Ressourcen nutzt. Mit serverbasierten Anwendungen wird sich das ändern. In dieser Welt werden Hardware und Software zusammen bereitgestellt. Für Unternehmen, die serverbasierte Anwendungen anbieten, wird es unterm Strich einen großen Unterschied machen, wie viele Benutzer sie pro Server unterstützen können.
Bei manchen Anwendungen ist der Prozessor der limitierende Faktor und die Ausführungsgeschwindigkeit das Wichtigste, was optimiert werden muss. Aber oft ist der Arbeitsspeicher die Grenze; die Anzahl gleichzeitiger Benutzer wird durch die Speichermenge bestimmt, die Sie für die Daten jedes Benutzers benötigen. Auch hier kann die Sprache hilfreich sein. Eine gute Thread-Unterstützung ermöglicht es allen Benutzern, einen einzigen Heap gemeinsam zu nutzen. Es kann auch hilfreich sein, persistente Objekte und/oder Unterstützung auf Sprachebene für Lazy Loading zu haben.
9 Zeit
Die letzte Zutat, die eine beliebte Sprache braucht, ist Zeit. Niemand möchte Programme in einer Sprache schreiben, die möglicherweise aus der Mode kommt, wie das bei vielen Programmiersprachen der Fall ist. Daher warten die meisten Hacker, bis eine Sprache schon ein paar Jahre existiert, bevor sie überhaupt in Erwägung ziehen, sie zu verwenden.
Erfinder wunderbarer neuer Dinge sind oft überrascht, wenn sie das entdecken, aber man braucht Zeit, um den Leuten eine Botschaft zu übermitteln. Ein Freund von mir tut selten etwas, wenn man ihn das erste Mal darum bittet. Er weiß, dass die Leute manchmal Dinge verlangen, die sie am Ende gar nicht wollen. Um seine Zeit nicht zu verschwenden, wartet er, bis er das dritte oder vierte Mal gebeten wird, etwas zu tun. Bis dahin ist derjenige, der ihn darum bittet, vielleicht ziemlich genervt, aber zumindest will er wahrscheinlich wirklich, worum er bittet.
Die meisten Menschen haben gelernt, neue Dinge, von denen sie hören, auf ähnliche Weise zu filtern. Sie fangen erst an, darauf zu achten, wenn sie etwas schon zehnmal gehört haben. Und das ist vollkommen richtig: Die meisten heißen neuen Dinge erweisen sich als Zeitverschwendung und verschwinden irgendwann. Indem ich das Erlernen von VRML hinauszögerte, musste ich es gar nicht erst lernen.
Wer also etwas Neues erfindet, muss damit rechnen, dass er seine Botschaft jahrelang wiederholen muss, bevor die Leute sie verstehen. Wir haben, soweit ich weiß, die erste webserverbasierte Anwendung geschrieben, und wir haben Jahre gebraucht, um den Leuten klarzumachen, dass sie diese nicht herunterladen müssen. Es war nicht so, dass sie dumm waren. Sie hatten uns einfach abgelenkt.
Die gute Nachricht ist, dass einfache Wiederholung das Problem löst. Sie müssen Ihre Geschichte nur immer wieder erzählen, und irgendwann werden die Leute anfangen, sie zu hören. Die Leute werden nicht aufmerksam, wenn sie bemerken, dass Sie da sind, sondern wenn sie bemerken, dass Sie immer noch da sind.
Es ist nur gut, dass es normalerweise eine Weile dauert, bis es an Fahrt gewinnt. Die meisten Technologien entwickeln sich auch nach ihrer Einführung noch stark weiter – insbesondere Programmiersprachen. Für eine neue Technologie gibt es nichts Besseres, als sie einige Jahre lang nur von einer kleinen Anzahl von Early Adopters zu verwenden. Early Adopters sind anspruchsvoll und räumen schnell alle noch verbliebenen Mängel Ihrer Technologie aus. 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, selbst wenn dies zu einigen Störungen führt.
Es gibt zwei Möglichkeiten, wie neue Technologien eingeführt werden: die Methode des organischen Wachstums und die Big-Bang-Methode. Die Methode des organischen Wachstums wird durch das klassische, aus dem Bauch heraus entstandene, unterfinanzierte Garagen-Startup veranschaulicht. Ein paar Typen, die im Verborgenen arbeiten, entwickeln eine neue Technologie. Sie bringen sie ohne Marketing auf den Markt und haben zunächst nur wenige (fanatisch ergebene) Benutzer. Sie verbessern die Technologie weiter und währenddessen wächst ihre Benutzerbasis durch Mundpropaganda. Ehe sie es merken, sind sie groß.
Der andere Ansatz, die Big-Bang-Methode, wird von VC-finanzierten, stark vermarkteten Startups veranschaulicht. Sie entwickeln in aller Eile ein Produkt, bringen es mit großer Publizität auf den Markt und haben (hoffentlich) sofort eine große Nutzerbasis.
Im Allgemeinen beneiden die Jungs aus der Garage die Jungs aus dem Big Bang. Die Jungs aus dem Big Bang sind lässig und selbstbewusst und werden von den Risikokapitalgebern respektiert. Sie können sich von allem das Beste leisten, und die PR-Kampagne rund um die Produkteinführung hat den Nebeneffekt, dass sie zu Berühmtheiten werden. Die Jungs aus dem organischen Wachstum, die in ihrer Garage sitzen, fühlen sich arm und ungeliebt. Und doch bemitleiden sie meiner Meinung nach oft fälschlicherweise Selbstmitleid. Organisches Wachstum scheint bessere Technologien und reichere Gründer hervorzubringen als die Big-Bang-Methode. Wenn Sie sich die heute vorherrschenden Technologien ansehen, werden Sie feststellen, dass die meisten von ihnen organisch gewachsen sind.
Dieses Muster gilt nicht nur für Unternehmen. Man kann es auch in der gesponserten Forschung beobachten. Multics und Common Lisp waren Big-Bang-Projekte, während Unix und MacLisp organische Wachstumsprojekte waren.
10 Neugestaltung
„Das beste Schreiben ist das Umschreiben“, schrieb EB White. Jeder gute Autor weiß das, und das gilt auch für Software. Der wichtigste Teil des Designs ist das Umgestalten. Insbesondere Programmiersprachen werden nicht oft genug umgestaltet.
Um gute Software zu schreiben, müssen Sie gleichzeitig zwei gegensätzliche Ideen im Kopf haben. Sie brauchen den naiven Glauben des jungen Hackers an seine Fähigkeiten und gleichzeitig die Skepsis des erfahrenen Hackers. Sie müssen in der Lage sein, mit der einen Hälfte Ihres Gehirns zu denken , „wie schwer kann das sein?“, während Sie mit der anderen Hälfte denken , dass es nie funktionieren wird .
Der Trick besteht darin, zu erkennen, dass es hier keinen wirklichen Widerspruch gibt. Sie möchten in Bezug auf zwei verschiedene Dinge optimistisch und skeptisch sein. Sie müssen optimistisch sein, was die Möglichkeit einer Problemlösung angeht, aber skeptisch, was den Wert der Lösung angeht, die Sie bisher gefunden haben.
Menschen, die gute Arbeit leisten, denken oft, dass das, woran sie arbeiten, nicht gut ist. Andere sehen, was sie getan haben, und sind voller Staunen, aber der Schöpfer ist voller Sorge. Dieses Muster ist kein Zufall: Es sind die Sorgen, die die Arbeit gut machen.
Wenn Sie Hoffnung und Sorge im Gleichgewicht halten können, werden sie ein Projekt genauso vorantreiben, wie Ihre beiden Beine ein Fahrrad vorantreiben. In der ersten Phase des zweizyklischen Innovationsmotors arbeiten Sie fieberhaft an einem Problem, beflügelt von Ihrer Zuversicht, dass Sie es lösen können. In der zweiten Phase betrachten Sie im kalten Licht des Morgens, was Sie getan haben, und sehen alle Mängel sehr deutlich. Aber solange Ihr kritischer Geist Ihre Hoffnung nicht überwiegt, werden Sie in der Lage sein, Ihr zugegebenermaßen unvollständiges System zu betrachten und zu denken: „Wie schwer kann es sein, den Rest des Weges zu erreichen?“, wodurch der Zyklus fortgesetzt wird.
Es ist schwierig, die Balance zwischen diesen beiden Kräften zu halten. Bei jungen Hackern überwiegt der Optimismus. Sie produzieren etwas, sind davon überzeugt, dass es großartig ist, und verbessern es nie. Bei alten Hackern überwiegt der Skeptizismus und sie trauen sich nicht einmal, ehrgeizige Projekte in Angriff zu nehmen.
Alles, was Sie tun können, um den Neugestaltungszyklus in Gang zu halten, ist gut. Prosa kann so lange neu geschrieben werden, bis Sie zufrieden sind. Software wird jedoch in der Regel nicht oft genug neu gestaltet. Prosa hat Leser, Software jedoch hat Benutzer. Wenn ein Autor einen Aufsatz neu schreibt, werden sich die Leute, die die alte Version lesen, wahrscheinlich nicht darüber beschweren, dass ihre Gedanken durch eine neu eingeführte Inkompatibilität beeinträchtigt wurden.
Benutzer sind ein zweischneidiges Schwert. Sie können Ihnen helfen, Ihre Sprache zu verbessern, sie können Sie aber auch davon abhalten, sie zu verbessern. Wählen Sie Ihre Benutzer also sorgfältig aus und lassen Sie deren Zahl langsam wachsen. Benutzer zu haben ist wie Optimierung: Es ist klug, sie hinauszuzögern. Außerdem können Sie sich in der Regel jederzeit mehr Änderungen erlauben, als Sie denken. Änderungen vorzunehmen ist wie ein Pflaster abzuziehen: Der Schmerz ist eine Erinnerung, fast 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 sich in die Neugestaltung einmischen. Es ist so viel Arbeit, Änderungen einzuführen, dass sich niemand damit beschäftigen möchte. Was auch immer ein Komitee entscheidet, bleibt in der Regel so, auch wenn es den meisten Mitgliedern nicht gefällt.
Sogar ein Komitee aus zwei Personen steht der Neugestaltung im Weg. Dies passiert insbesondere bei Schnittstellen zwischen Softwareteilen, die von zwei verschiedenen Personen geschrieben wurden. Um die Schnittstelle zu ändern, müssen beide zustimmen, sie sofort zu ändern. Und so ändern sich Schnittstellen in der Regel überhaupt nicht, was ein Problem darstellt, da sie in der Regel einer der am meisten ad hoc arbeitenden Teile eines Systems sind.
Eine Lösung könnte darin bestehen, Systeme so zu gestalten, dass die Schnittstellen horizontal statt vertikal sind – so dass Module immer vertikal gestapelte Abstraktionsschichten sind. Dann wird die Schnittstelle tendenziell einer von ihnen gehören. Die untere von zwei Ebenen wird entweder eine Sprache sein, in der die obere geschrieben ist. In diesem Fall wird die untere Ebene die Schnittstelle besitzen, oder sie wird ein Slave sein, in diesem Fall kann die Schnittstelle von der oberen Ebene diktiert werden.
11 Lisp
All dies impliziert, dass es Hoffnung für ein neues Lisp gibt. Es gibt Hoffnung für jede Sprache, die Hackern gibt, was sie wollen, einschließlich Lisp. Ich denke, wir haben uns vielleicht geirrt, als wir dachten, dass Hacker von der Fremdartigkeit von Lisp abgeschreckt werden. Diese beruhigende Illusion hat uns vielleicht daran gehindert, das wahre Problem mit Lisp oder zumindest Common Lisp zu erkennen, nämlich, dass es nicht das tut, was Hacker tun wollen. Eine Hackersprache braucht leistungsstarke Bibliotheken und etwas zum Hacken. Common Lisp hat beides nicht. Eine Hackersprache ist knapp und hackbar. Common Lisp ist das nicht.
Die gute Nachricht ist, dass nicht Lisp, sondern Common Lisp Mist ist. Wenn wir ein neues Lisp entwickeln können, das eine echte Hackersprache ist, werden Hacker es meiner Meinung nach verwenden. Sie werden jede Sprache verwenden, die die Aufgabe erfüllt. Wir müssen nur sicherstellen, dass dieses neue Lisp eine wichtige Aufgabe besser erfüllt als andere Sprachen.
Die Geschichte bietet einiges an Ermutigung. 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 Sie geschaffen haben, Lisp ist. Die neueste angesagte Sprache, Python, ist ein verwässertes Lisp mit Infix-Syntax und ohne Makros. Ein neues Lisp wäre ein natürlicher Schritt in dieser Entwicklung.
Manchmal denke ich, es wäre ein guter Marketingtrick, es 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-Worts. Aber ich denke, wir sollten keine Angst haben, das neue Lisp Lisp zu nennen. Lisp genießt unter den allerbesten Hackern immer noch eine Menge latenten Respekt – zum Beispiel bei denen, die 6.001 genommen und verstanden haben. 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 Sie als geistige Übung lernen sollten, auch wenn Sie sie nicht wirklich verwenden werden:
Das Erlernen von Lisp lohnt sich schon wegen des tiefen Erleuchtungserlebnisses, das Sie haben werden, wenn Sie es endlich beherrschen; diese Erfahrung wird Sie für den Rest Ihres Lebens zu einem besseren Programmierer machen, selbst wenn Sie Lisp selbst nie wirklich oft verwenden.
Wenn ich Lisp nicht kennen würde, würde ich mir beim Lesen dieses Artikels Fragen stellen. Eine Sprache, die mich zu einem besseren Programmierer machen würde, bedeutet – wenn überhaupt – eine Sprache, die sich besser zum Programmieren eignet. Und das ist tatsächlich die Implikation dessen, was Eric sagt.
Solange diese Idee noch im Umlauf ist, werden Hacker meiner Meinung nach für ein neues Lisp empfänglich genug sein, selbst wenn es Lisp heißt. Aber dieses Lisp muss eine Hackersprache sein, wie die klassischen Lisps der 1970er Jahre. Es muss knapp, einfach und hackbar sein. Und es muss über leistungsstarke Bibliotheken verfügen, um das zu tun, was Hacker jetzt tun wollen.
In Sachen Bibliotheken denke ich, dass es Möglichkeiten gibt, Sprachen wie Perl und Python mit ihren eigenen Waffen 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 neues Lisp nicht ebenso gute String-Bibliotheken wie Perl haben sollte, und wenn dieses neue Lisp auch leistungsstarke Bibliotheken für serverbasierte Anwendungen hätte, könnte es sehr beliebt sein. Echte Hacker werden nicht die Nase rümpfen über ein neues Tool, mit dem sie schwierige Probleme mit ein paar Bibliotheksaufrufen lösen können. Denken Sie daran, Hacker sind faul.
Ein noch größerer Gewinn könnte es sein, wenn es Kernsprachenunterstützung für serverbasierte Anwendungen gäbe. Beispielsweise explizite Unterstützung für Programme mit mehreren Benutzern oder Dateneigentum auf der Ebene von Typ-Tags.
Serverbasierte Anwendungen geben uns auch die Antwort auf die Frage, was mit diesem neuen Lisp gehackt werden soll. Es würde nicht schaden, Lisp als Skriptsprache für Unix zu verbessern. (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, die Wirkung von Unterprogrammen 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 geeignet, um es zu generieren. Es müssen bessere Tools zum Schreiben serverbasierter Anwendungen her, und es muss ein neues Lisp her, und die beiden würden sehr gut zusammenarbeiten.
12 Die Traumsprache
Versuchen wir zusammenfassend, die Traumsprache des Hackers zu beschreiben. Die Traumsprache ist schön , sauber und prägnant. Sie hat eine interaktive Toplevel-Sprache, die schnell startet. Sie können Programme schreiben, um gängige 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 übertrieben kurz. Sie müssen nie ein unnötiges Zeichen eingeben oder die Umschalttaste häufig verwenden.
Mithilfe großer Abstraktionen können Sie die erste Version eines Programms sehr schnell schreiben. Wenn Sie später optimieren möchten, gibt es einen wirklich guten Profiler, der Ihnen sagt, worauf Sie Ihre Aufmerksamkeit richten müssen. Sie können blitzschnell innere Schleifen erstellen und bei Bedarf sogar Inline-Bytecode schreiben.
Es gibt viele gute Beispiele, von denen man lernen kann, und die Sprache ist intuitiv genug, sodass Sie ihre Verwendung anhand von Beispielen in wenigen Minuten erlernen können. Sie müssen nicht lange im Handbuch nachschlagen. Das Handbuch ist dünn und enthält nur wenige Warnungen und Einschränkungen.
Die Sprache hat einen kleinen Kern und leistungsstarke, hochgradig orthogonale Bibliotheken, die ebenso sorgfältig entwickelt wurden wie die Kernsprache. Die Bibliotheken arbeiten alle gut zusammen; alles in der Sprache passt zusammen wie die Teile einer guten Kamera. Nichts ist veraltet oder wurde aus Kompatibilitätsgründen beibehalten. Der Quellcode aller Bibliotheken ist leicht verfügbar. Es ist einfach, mit dem Betriebssystem und mit Anwendungen zu kommunizieren, die in anderen Sprachen geschrieben sind.
Die Sprache ist in Schichten aufgebaut. Die Abstraktionen höherer Ebene werden auf sehr transparente Weise aus Abstraktionen niedrigerer Ebene aufgebaut, auf die Sie bei Bedarf zugreifen können.
Nichts bleibt vor Ihnen verborgen, was nicht unbedingt sein muss. Die Sprache bietet Abstraktionen nur an, um Ihnen Arbeit zu ersparen, und nicht, um Ihnen zu sagen, was Sie tun sollen. Tatsächlich ermutigt Sie die Sprache, gleichberechtigt an ihrer Gestaltung mitzuwirken. Sie können alles daran ändern, sogar die Syntax, und alles, was Sie schreiben, hat so weit wie möglich denselben Status wie das, was vordefiniert ist.
Hinweise
[1] Makros, die der modernen Idee sehr nahe kommen, wurden 1964 von Timothy Hart vorgeschlagen, zwei Jahre nach der Veröffentlichung von Lisp 1.5. Was anfangs fehlte, waren Möglichkeiten, die Variablenerfassung und Mehrfachauswertung zu vermeiden; Harts Beispiele unterliegen beidem.
[2] In „When the Air Hits Your Brain“ gibt der Neurochirurg Frank Vertosick ein Gespräch wieder, in dem sein Chefarzt Gary über den Unterschied zwischen Chirurgen und Internisten („Flöhen“) spricht:
Gary und ich bestellten eine große Pizza und fanden eine freie Sitznische. Der Chef zündete sich eine Zigarette an. „Sehen Sie sich diese verdammten Flöhe an, die von irgendeiner Krankheit faseln, die sie nur einmal in ihrem Leben sehen. Das ist das Problem mit Flöhen, sie mögen nur das bizarre Zeug. Sie hassen ihre Brot-und-Butter-Fälle. Das ist der Unterschied zwischen uns und den verdammten Flöhen. Sehen Sie, wir lieben große, saftige Bandscheibenvorfälle in der Lendenwirbelsäule, aber sie hassen Bluthochdruck …“
Es ist schwer, einen Bandscheibenvorfall in der Lendenwirbelsäule als pikant zu betrachten (außer im wörtlichen Sinne). Und doch glaube ich zu wissen, was damit gemeint ist. Ich hatte schon oft einen pikanter Bug, den ich aufspüren musste. Jemand, der kein Programmierer ist, kann sich kaum vorstellen, dass ein Bug Spaß machen kann. Sicher ist es besser, wenn einfach alles funktioniert. In gewisser Weise ist es das auch. Und doch ist es unbestreitbar eine grimmige Befriedigung, bestimmte Arten von Bugs aufzuspüren.