Loading...

BELIEBT SEIN

Original

Mai 2001

(Dieser Artikel wurde als eine Art Geschäftsplan für eine neue Sprache geschrieben. Daher fehlt (weil es als selbstverständlich vorausgesetzt wird) das wichtigste Merkmal einer guten Programmiersprache: sehr leistungsfähige Abstraktionen.)

Ein Freund von mir erzählte einmal einem angesehenen Betriebssystem- experten, dass er eine wirklich gute Programmiersprache entwerfen wolle. Der Experte sagte ihm, dass es eine Verschwendung von Zeit wäre, da Programmiersprachen nicht aufgrund ihrer Verdienste populär oder unpopulär würden, und daher, egal wie gut seine Sprache auch sei, niemand sie benutzen würde. Zumindest, so war es bei der Sprache, 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ürden Sie das machen?

Ich denke, die Antworten auf diese Fragen lassen sich finden, indem man Hacker betrachtet und herausfindet, was sie wollen. Programmiersprachen sind für Hacker da, und eine Programmiersprache ist als Programmiersprache gut (anstatt, sagen wir, eine Übung in denotationaler Semantik oder Compilerkonstruktion zu sein), wenn und nur wenn Hacker sie mögen.

1 Die Mechanik der Popularität

Es ist sicherlich wahr, dass die meisten Menschen Programmiersprachen nicht einfach aufgrund ihrer Verdienste wählen. Die meisten Programmierer werden von jemandem anderem angewiesen, welche Sprache sie benutzen sollen. Und doch denke 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 die, die zählt. Programmiersprachen sind keine Theoreme. Sie sind Werkzeuge, die für Menschen entwickelt wurden, und sie müssen so konzipiert sein, dass sie menschliche Stärken und Schwächen ebenso berücksichtigen wie Schuhe für menschliche Füße konzipiert sein müssen. Wenn ein Schuh drückt, wenn man ihn anzieht, ist er ein schlechter Schuh, wie elegant er auch als Skulptur sein mag.

Es kann sein, dass die Mehrheit der Programmierer keinen guten von einem schlechten Programm unterscheiden kann. Aber das ist bei jedem anderen Werkzeug nicht anders. Das bedeutet nicht, dass es eine Verschwendung von Zeit ist, zu versuchen, eine gute Sprache zu entwerfen. Erfahrene Hacker können eine gute Sprache erkennen, wenn sie sie sehen, und sie werden sie benutzen. Erfahrene Hacker sind sicherlich eine kleine Minderheit, aber diese kleine Minderheit schreibt die gesamte gute Software, und ihr Einfluss ist so groß, dass die anderen Programmierer dazu tendieren, die Sprache zu benutzen, die sie benutzen. Oft ist es in der Tat nicht nur Einfluss, sondern Befehl: Oft sind die erfahrenen Hacker die Leute, die als ihre Vorgesetzten oder Fakultätsberater den anderen Programmierern sagen, welche Sprache sie benutzen sollen.

Die Meinung erfahrener Hacker ist nicht die einzige Kraft, die die relative Popularität von Programmiersprachen bestimmt - Legacy-Software (Cobol) und Hype (Ada, Java) spielen auch eine Rolle -, aber ich denke, sie ist die mächtigste Kraft auf lange Sicht. Wenn eine kritische Masse erreicht ist und genug Zeit vergeht, wird eine Programmiersprache wahrscheinlich etwa so populär, wie sie es verdient. Und Popularität trennt gute Sprachen weiter von schlechten, denn Feedback von echten Nutzern führt immer zu Verbesserungen. Schauen Sie sich an, wie sehr sich jede populäre Sprache im Laufe ihrer Existenz 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 lang Lisp benutzt hatten, um echte Programme zu schreiben. [1]

Ob eine Sprache also gut sein muss, um populär zu werden 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 Mitte der 1980er Jahre am MIT waren, weil das der letzte Zeitpunkt war, an dem Lisp eine ausreichend große und anspruchsvolle Nutzerbasis hatte.

Natürlich müssen Hacker von einer Sprache erfahren, bevor sie sie benutzen können. Woher sollen sie davon hören? Von anderen Hackern. Aber es muss eine Anfangsgruppe von Hackern geben, die die Sprache benutzen, damit andere überhaupt davon hören. Ich frage mich, wie groß diese Gruppe sein muss; wie viele Nutzer machen eine kritische Masse aus? Aus dem Stegreif würde ich sagen, zwanzig. Wenn eine Sprache zwanzig separate Nutzer hätte, was bedeutet, dass zwanzig Nutzer sich unabhängig voneinander dafür entschieden haben, sie zu benutzen, würde ich sie als real betrachten.

Dorthin zu kommen, kann nicht einfach sein. Ich wäre nicht überrascht, wenn es schwieriger wäre, von null auf zwanzig zu kommen, als von zwanzig auf tausend. Der beste Weg, diese ersten zwanzig Nutzer zu bekommen, ist wahrscheinlich, ein Trojanisches Pferd zu verwenden: den Leuten eine Anwendung zu geben, die sie wollen, die zufällig in der neuen Sprache geschrieben ist.

2 Externe Faktoren

Lassen Sie uns zunächst einen externen Faktor anerkennen, der die Popularität einer Programmiersprache tatsächlich 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 dazu bestimmt, die Skriptsprachen von Webbrowsern zu sein.

Lisp ist keine massiv populäre Sprache, weil es nicht die Skriptsprache eines massiv populären Systems ist. Die Popularität, die es noch hat, reicht zurück in die 1960er und 1970er Jahre, als es die Skriptsprache des MIT war. Viele der großen Programmierer der damaligen Zeit waren irgendwann mit dem MIT verbunden. Und Anfang der 1970er Jahre, bevor C, war der MIT-Dialekt von Lisp, genannt MacLisp, eine der einzigen Programmiersprachen, die ein ernsthafter Hacker benutzen wollte.

Heute ist Lisp die Skriptsprache von zwei mäßig populären Systemen, Emacs und Autocad, und aus diesem Grund vermute ich, dass der Großteil der Lisp- Programmierung, die heute stattfindet, in Emacs Lisp oder AutoLisp geschrieben wird.

Programmiersprachen existieren nicht isoliert. Zu hacken ist ein transitives Verb - Hacker hacken normalerweise etwas - und in der Praxis werden Sprachen im Verhältnis zu dem beurteilt, was damit gehackt wird. Wenn Sie also eine populäre Sprache entwerfen wollen, müssen Sie entweder mehr als nur eine Sprache liefern oder Ihre Sprache so entwerfen, dass sie die Skriptsprache eines bestehenden Systems ersetzt.

Common Lisp ist teilweise unpopulär, weil es eine Waise ist. Es kam ursprünglich mit einem System zum Hacken: der Lisp-Maschine. Aber Lisp-Maschinen (zusammen mit Parallelrechnern) wurden von der zunehmenden Leistungsfähigkeit allgemeiner Prozessoren in den 1980er Jahren überrollt. Common Lisp hätte vielleicht populär geblieben, wenn es eine gute Skriptsprache für Unix gewesen wäre. Leider ist es eine entsetzlich schlechte.

Eine Möglichkeit, diese Situation zu beschreiben, ist zu sagen, dass eine Sprache nicht nach ihren eigenen Verdiensten beurteilt wird. Eine andere Sicht ist, dass eine Programmiersprache wirklich keine Programmiersprache ist, es sei denn, sie ist auch die Skriptsprache von etwas. Das erscheint nur dann unfair, wenn es überraschend kommt. Ich denke, es ist nicht unfairer, als von einer Programmiersprache zu erwarten, dass sie zum Beispiel eine Implementierung hat. Es ist einfach Teil dessen, was eine Programmiersprache ist.

Eine Programmiersprache braucht natürlich eine gute Implementierung, und diese muss kostenlos sein. Unternehmen werden für Software bezahlen, aber individuelle Hacker nicht, und es sind die Hacker, die man anziehen muss.

Eine Sprache muss auch ein Buch darüber haben. Das Buch sollte dünn, gut geschrieben und voller guter Beispiele sein. K&R ist hier das Ideal. Momentan würde ich fast sagen, dass eine Sprache ein Buch haben muss, das von O'Reilly veröffentlicht wurde. Das wird zum Test dafür, dass sie für Hacker von Bedeutung ist.

Es sollte auch Online-Dokumentation geben. Tatsächlich kann das Buch als Online-Dokumentation beginnen. Aber ich denke nicht, dass gedruckte Bücher schon veraltet sind. Ihr Format ist praktisch, und die de-facto-Zensur, die von Verlagen ausgeübt wird, ist ein nützlicher, wenn auch unvollkommener Filter. Buchhandlungen sind einer der wichtigsten Orte, um neue Sprachen kennenzulernen.

3 Kürze

Angenommen, Sie können die drei Dinge liefern, die eine Sprache braucht - eine kostenlose Implementierung, ein Buch und etwas zum Hacken -, wie machen Sie dann eine Sprache, die Hacker mögen?

Eine Sache, die Hacker mögen, ist Kürze. Hacker sind faul, genauso wie Mathematiker und modernistische Architekten faul sind: Sie hassen alles Überflüssige. Es wäre nicht weit von der Wahrheit entfernt zu sagen, dass ein Hacker, bevor er ein Programm schreibt, zumindest unterbewusst entscheidet, welche Sprache er aufgrund der Gesamtzahl der Zeichen, die er tippen muss, verwenden wird. Wenn dies nicht genau die Art und Weise ist, wie Hacker denken, dann täte ein Sprachdesigner gut daran, so zu handeln, als wäre es so.

Es ist ein Fehler, den Benutzer mit weitschweifigen Ausdrücken, die dem Englischen ähneln sollen, zu bemuttern. Cobol ist für diesen Mangel berüchtigt. Ein Hacker würde es als etwas zwischen einer Beleidigung seiner Intelligenz und einer Sünde gegen Gott empfinden, wenn er gebeten würde, zu schreiben

add x to y giving z

anstelle von

z = x+y

Es wurde manchmal gesagt, dass Lisp first und rest anstelle von car und cdr verwenden sollte, weil es Programme lesbarer 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 so gut ausgerichtet sind, wenn sie, wie car und cdr oft, in aufeinanderfolgenden Zeilen aufgerufen werden. Ich habe festgestellt, dass es sehr wichtig ist, wie der Code auf der Seite ausgerichtet ist. Ich kann Lisp-Code kaum lesen, wenn er in einer variablenbreiten Schrift gesetzt ist, und Freunde sagen, dass dies auch für andere Sprachen gilt.

Kürze ist ein Bereich, in dem stark typisierte Sprachen verlieren. Alles andere gleich, will niemand mit einer Reihe von Deklarationen am Anfang eines Programms beginnen. Alles, was implizit sein kann, sollte es auch sein.

Auch die einzelnen Token sollten kurz sein. Perl und Common Lisp besetzen entgegengesetzte Pole in dieser Frage. Perl-Programme können fast kryptisch dicht sein, während die Namen der eingebauten Common-Lisp-Operatoren komisch lang sind. Die Entwickler von Common Lisp haben wahrscheinlich erwartet, dass die Benutzer Textbearbeitungsprogramme haben, die diese langen Namen für sie eintippen. Aber die Kosten eines langen Namens sind nicht nur die Kosten des Tippens. Es gibt auch die Kosten des Lesens und den Platz, den er auf dem Bildschirm einnimmt.

4 Hackbarkeit

Es gibt eine Sache, die für einen Hacker wichtiger ist als Kürze: in der Lage zu sein, zu tun, was man will. In der Geschichte der Programmiersprachen wurde erstaunlich viel Mühe darauf verwendet, Programmierer daran zu hindern, Dinge zu tun, die als unangemessen angesehen werden. Das ist ein gefährlich anmaßender Plan. Wie kann der Sprachdesigner wissen, was der Programmierer tun muss? Ich denke, Sprachdesigner täten besser daran, ihren Zielbenutzer als einen Genie zu betrachten, der Dinge tun muss, die sie nie erwartet haben, anstatt als einen Trottel, der vor sich selbst geschützt werden muss. Der Trottel wird sich sowieso in den Fuß schießen. Sie mögen ihn davor bewahren, Variablen in einem anderen Paket zu referenzieren, aber sie können ihn nicht davor bewahren, ein schlecht entworfenes Programm zu schreiben, um das falsche Problem zu lösen und ewig daran zu arbeiten.

Gute Programmierer wollen oft gefährliche und unsaubere Dinge tun. Mit unsauber meine ich Dinge, die hinter der semantischen Fassade der Sprache liegen: zum Beispiel an die interne Darstellung einer hochrangigen Abstraktion herankommen. Hacker mögen es zu hacken, und Hacken bedeutet, in Dinge einzudringen und den ursprünglichen Designer zu überlisten.

Lassen Sie sich überlisten. Wenn Sie ein Werkzeug herstellen, verwenden die Leute es auf Arten, die Sie nicht beabsichtigt haben, und das gilt besonders für ein hochartifizielles Werkzeug wie eine Programmiersprache. Viele Hacker werden Ihre semantische Modell auf eine Weise verfeinern wollen, die Sie nie erwartet haben. Ich sage, lassen Sie sie; geben Sie dem Programmierer so viel Zugriff auf interne Dinge wie möglich, ohne die Laufzeitsysteme wie den Garbage Collector zu gefährden.

In Common Lisp habe ich oft die Felder einer Struktur durchlaufen wollen - um Referenzen auf ein gelöschtes Objekt herauszufinden oder Felder zu finden, die nicht initialisiert sind. Ich weiß, dass die Strukturen darunter einfach Vektoren sind. Und doch kann ich keine allgemeingültige Funktion schreiben, die ich auf jede Struktur aufrufen kann. Ich kann nur über die Feldnamen darauf zugreifen, denn das ist die Bedeutung einer Struktur.

Ein Hacker möchte das beabsichtigte Modell der Dinge vielleicht nur ein- oder zweimal in einem großen Programm unterlaufen. Aber was für einen Unterschied macht es, das tun zu können. Und es kann mehr sein als nur ein Problem zu lösen. Es gibt hier auch eine Art Vergnügen. Hacker teilen die geheime Freude des Chirurgen am Herumstochern in ekligen Eingeweiden, die geheime Freude des Teenagers am Ausdrücken von Pickeln. [2] Für Jungen zumindest sind bestimmte Arten von Schrecken faszinierend. Maxim Magazine veröffentlicht jährlich einen Band mit Fotografien, 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 Abweichung. Frühe Lisps ließen dich alles in die Finger bekommen. Zum Glück ist ein Großteil dieses Geistes in Makros erhalten geblieben. Was für eine wunderbare Sache, beliebige Transformationen am Quellcode vornehmen zu können.

Klassische Makros sind ein echtes Werkzeug für Hacker - einfach, mächtig und gefährlich. Es ist so einfach zu verstehen, was sie tun: Du rufst eine Funktion mit den Argumenten des Makros auf, und was auch immer sie zurückgibt, wird an Stelle des Makroaufrufs eingefügt. Hygienische Makros verkörpern das gegenteilige Prinzip. Sie versuchen, dich 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, zu entscheiden, was Programmierer wollen dürfen. Hygienische Makros sollen mich unter anderem vor Variableneinfang schützen, aber Variableneinfang ist genau das, was ich in manchen Makros will.

Eine wirklich gute Sprache sollte sowohl sauber als auch schmutzig sein: sauber entworfen, mit einem kleinen Kern von gut verstandenen und hochgradig orthogonalen Operatoren, aber schmutzig in dem Sinne, dass sie Hackern erlaubt, nach ihrer Façon mit ihr umzugehen. C ist so eine Sprache. Genauso waren es die frühen Lisps. Eine echte Hackersprache wird immer einen leicht zwielichtigen Charakter haben.

Eine gute Programmiersprache sollte Merkmale haben, die die Leute, die den Begriff "Softwareentwicklung" verwenden, missbilligend den Kopf schütteln lassen. Am anderen Ende des Spektrums befinden sich Sprachen wie Ada und Pascal, Musterbeispiele der Anständigkeit, die gut zum Unterrichten, aber sonst nicht viel taugen.

5 Wegwerfprogramme

Um für Hacker attraktiv zu sein, muss eine Sprache gut darin sein, die Arten von Programmen zu schreiben, die sie schreiben wollen. Und das bedeutet, vielleicht überraschenderweise, dass sie gut darin sein muss, Wegwerfprogramme zu schreiben.

Ein Wegwerfprogramm ist ein Programm, das du schnell für eine begrenzte Aufgabe schreibst: ein Programm, um eine Systemadministrationsaufgabe zu automatisieren, Testdaten für eine Simulation zu generieren oder Daten von einem Format in ein anderes zu konvertieren. Das Überraschende an Wegwerfprogrammen ist, dass sie, wie die "vorübergehenden" 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 Nutzern weiter.

Ich vermute, dass die besten großen Programme so beginnen, anstatt von Anfang an groß entworfen zu werden, wie der Hoover-Damm. Es ist furchteinflößend, etwas Großes von Grund auf zu bauen. Wenn Leute ein Projekt angehen, das zu groß ist, werden sie überwältigt. Das Projekt kommt entweder ins Stocken oder das Ergebnis ist steril und hölzern: ein Einkaufszentrum anstelle einer echten Innenstadt, Brasília anstelle von Rom, Ada anstelle von C.

Eine andere Möglichkeit, ein großes Programm zu bekommen, ist, mit einem Wegwerfprogramm zu beginnen und es ständig zu verbessern. Dieser Ansatz ist weniger einschüchternd, und das Design des Programms profitiert von der Evolution. Ich denke, wenn man danach suchen würde, würde sich herausstellen, dass dies der Weg ist, auf dem die meisten großen Programme entwickelt wurden. Und diejenigen, die sich so entwickelt haben, werden wahrscheinlich immer noch in der Sprache geschrieben sein, in der sie zuerst geschrieben wurden, denn es ist selten, dass ein Programm portiert wird, außer aus politischen Gründen. Und so ist es paradoxerweise, wenn du eine Sprache entwickeln willst, die für große Systeme verwendet wird, musst du sie gut dafür machen, Wegwerfprogramme zu schreiben, denn daraus kommen die großen Systeme.

Perl ist ein schlagendes Beispiel für diese Idee. Es wurde nicht nur zum Schreiben von Wegwerfprogrammen entworfen, sondern war selbst so ziemlich ein Wegwerfprogramm. Perl entstand als eine Sammlung von Dienstprogrammen zum Generieren von Berichten und entwickelte sich erst im Laufe der Zeit zu einer Programmiersprache weiter, als die Wegwerfprogramme, die die Leute damit schrieben, größer wurden. Erst mit Perl 5 (wenn überhaupt) war die Sprache geeignet, ernsthafte Programme zu schreiben, und doch war sie bereits massiv populär.

Was macht eine Sprache gut für Wegwerfprogramme? Zunächst einmal muss sie leicht verfügbar sein. Ein Wegwerfprogramm ist etwas, von dem du erwartest, es in einer Stunde zu schreiben. Also muss die Sprache wahrscheinlich bereits auf dem Computer installiert sein, den du verwendest. Es kann nicht etwas sein, das du erst installieren musst, bevor du es benutzt. Es muss einfach 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 deiner es bereits installiert hatte.

Verfügbar zu sein bedeutet aber mehr, als nur installiert zu sein. Eine interaktive Sprache mit einer Befehlszeilenschnittstelle ist verfügbarer als eine, die du kompilieren und separat ausführen musst. Eine populäre Programmiersprache sollte interaktiv sein und schnell starten.

Etwas anderes, was du in einem Wegwerfprogramm willst, ist Kürze. Kürze ist für Hacker immer attraktiv, und nie mehr als in einem Programm, das sie in einer Stunde fertigstellen wollen.

6 Bibliotheken

Die letztendliche Kürze ist natürlich, wenn das Programm bereits geschrieben ist und du es nur aufrufen musst. Und das bringt uns zu etwas, was meiner Meinung nach ein immer wichtigerer Aspekt von Programmiersprachen sein wird: Bibliotheksfunktionen. Perl gewinnt, weil es große Bibliotheken zum Manipulieren von Zeichenketten hat. Diese Art von Bibliotheksfunktionen sind besonders wichtig für Wegwerfprogramme, die oft ursprünglich zum Konvertieren oder Extrahieren von Daten geschrieben werden. Viele Perl-Programme beginnen wahrscheinlich einfach 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 glaube, zukünftige Programmiersprachen werden Bibliotheken haben, die genauso sorgfältig entworfen sind wie die Kernsprache. Programmiersprachen-Design wird nicht mehr darum gehen, ob man seine Sprache stark oder schwach typisiert, objektorientiert oder funktional machen soll, oder was auch immer, sondern darum, wie man großartige Bibliotheken entwirft. Die Art von Sprachdesignern, die gerne darüber nachdenken, wie man Typsysteme entwerfen kann, werden davor erschaudern. Es ist fast, als würde man Anwendungen schreiben! Zu schade. Sprachen sind für Programmierer da, und Bibliotheken sind es, was Programmierer brauchen.

Es ist schwierig, gute Bibliotheken zu entwerfen. Es ist nicht einfach eine Frage davon, viel Code zu schreiben. 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 orthogonaler 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 Mängel aufweist. Es gibt nur rudimentäre Bibliotheken zum Manipulieren von Zeichenketten und fast keine zum Kommunizieren mit dem Betriebssystem. Aus historischen Gründen versucht Common Lisp, so zu tun, als existiere das Betriebssystem nicht. Und da man nicht mit dem Betriebssystem kommunizieren kann, ist es unwahrscheinlich, dass man ein ernsthaftes Programm nur mit den eingebauten Operatoren in Common Lisp schreiben kann. Man muss auch implementierungsspezifische Tricks verwenden, und in der Praxis bieten diese einem nicht alles, was man möchte. Hacker würden Lisp viel höher einschätzen, wenn Common Lisp leistungsfähige Zeichenkettenbibliothe-ken und gute Betriebssystemunterstützung hätte.

7 Syntax

Könnte eine Sprache mit Lisps Syntax oder genauer gesagt, Mangel an Syntax, jemals populär werden? Ich weiß die Antwort auf diese Frage nicht. Ich denke jedoch, dass Syntax nicht der Hauptgrund dafür ist, dass Lisp derzeit nicht populär ist. Common Lisp hat schlimmere Probleme als eine unvertraute Syntax. Ich kenne mehrere Programmierer, die mit Präfixsyntax vertraut sind und dennoch standardmäßig Perl verwenden, weil es leistungsfähige Zeichenkettenbibliothe-ken hat und mit dem Betriebssystem kommunizieren kann.

Es gibt zwei mögliche Probleme mit der Präfixnotation: dass sie für Programmierer unvertraut ist und dass sie nicht dicht genug ist. Die gängige Weisheit in der Lisp-Welt ist, dass das erste Problem das eigentliche ist. Ich bin mir da nicht so sicher. Ja, die Präfixnotation versetzt gewöhnliche Programmierer in Panik. Aber ich glaube nicht, dass die Meinungen gewöhnlicher Programmierer zählen. Sprachen werden auf der Grundlage dessen, was Experten-Hacker von ihnen halten, populär oder unpopulär, und ich denke, Experten-Hacker könnten mit der Präfixnotation umgehen. Perl-Syntax kann ziemlich unverständlich sein, aber das hat der Popularität von Perl keinen Abbruch getan. Möglicherweise hat es sogar dazu beigetragen, eine Perl-Sekte zu fördern.

Ein ernsthafteres Problem ist die Weitschweifigkeit 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 einen Weg, das Problem zu umgehen. Wenn wir Datenstrukturen so behandeln, als wären sie Funktionen auf Indizes, könnten wir (a x y) schreiben, was sogar kürzer ist als die Perl-Form. Ähnliche Tricks könnten andere Arten von Ausdrücken verkürzen.

Wir können viele Klammern (oder optional machen) durch Einführung von bedeutsamer Einrückung loswerden. So lesen Programmierer sowieso Code: Wenn die Einrückung etwas anderes sagt als die Begrenzungszeichen, gehen wir nach der Einrückung. Die Behandlung von Einrückung als bedeutsam würde diese häufige Fehlerquelle beseitigen und Programme gleichzeitig kürzer machen.

Manchmal ist Infixsyntax leichter zu lesen. Das gilt besonders für mathematische Ausdrücke. Ich habe mein ganzes Programmierleben lang Lisp verwendet und finde Präfixausdrücke für mathematische Operationen immer noch nicht natürlich. Und doch ist es bequem, vor allem wenn man Code generiert, Operatoren zu haben, die eine beliebige Anzahl von Argumenten annehmen. Wenn wir also Infixsyntax haben, sollte sie wahrscheinlich als eine Art Read-Makro implementiert werden.

Ich denke nicht, dass wir religiös gegen die Einführung von Syntax in Lisp sein sollten, solange sie sich auf gut verstandene Weise in zugrunde liegende S-Ausdrücke übersetzt. Es gibt in Lisp bereits eine gute Portion Syntax. Es muss nicht unbedingt schlecht sein, mehr einzuführen, solange niemand gezwungen ist, sie zu verwenden. In Common Lisp sind einige Begrenzungszeichen für die Sprache reserviert, was darauf hindeutet, dass zumindest einige der Entwickler beabsichtigten, in Zukunft mehr Syntax einzuführen.

Eines der am meisten unlispischen Syntaxelemente in Common Lisp tritt in Formatzeichenketten auf; format ist eine eigene Sprache, und diese Sprache ist nicht Lisp. Wenn es einen Plan für die Einführung von mehr Syntax in Lisp gäbe, könnten Formatspezifikatoren möglicherweise darin aufgenommen werden. Es wäre gut, wenn Makros Formatspezifikatoren genauso generieren könnten wie jede andere Art von Code.

Ein angesehener Lisp-Hacker sagte mir, dass sein Exemplar von CLTL beim Abschnitt format aufschlägt. Meins auch. Das deutet wahrscheinlich auf Verbesserungspotenzial hin. Es kann auch bedeuten, dass Programme viel E/A machen.

8 Effizienz

Eine gute Sprache, wie jeder weiß, sollte schnellen Code erzeugen. Aber in der Praxis glaube ich nicht, dass schneller Code in erster Linie von Dingen kommt, die man beim Sprachentwurf 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 ist der Weg zu schnellem Code also, einen sehr guten Profiler zu haben, anstatt zum Beispiel die Sprache stark typisiert zu machen. Man muss nicht den Typ jedes Arguments in jedem Aufruf im Programm kennen. Man muss die Typen der Argumente in den Engpässen erklären können. Und noch wichtiger, man muss in der Lage sein, herauszufinden, wo die Engpässe sind.

Ein Kritikpunkt, den Leute an Lisp hatten, ist, dass es schwierig ist, zu erkennen, was teuer ist. Das könnte stimmen. Es könnte auch unvermeidbar sein, wenn man eine sehr abstrakte Sprache haben möchte. Und in jedem Fall denke ich, dass ein guter Profiler einen großen Teil des Problems beheben würde: Man würde schnell lernen, was teuer ist.

Ein Teil des Problems liegt hier in sozialen Faktoren. Sprachdesigner mögen es, schnelle Compiler zu schreiben. Daran messen sie ihre Fähigkeiten. Sie sehen den Profiler bestenfalls als Zusatz. Aber in der Praxis kann ein guter Profiler mehr dazu beitragen, die Geschwindigkeit tatsächlich geschriebener Programme in der Sprache zu verbessern, als ein Compiler, der schnellen Code erzeugt. Auch hier sind Sprachdesigner etwas von ihren Benutzern entfremdet. Sie lösen wirklich gut ein leicht falsches Problem.

Es wäre vielleicht eine gute Idee, einen aktiven Profiler zu haben - Leistungsdaten an den Programmierer weiterzuleiten, anstatt darauf zu warten, dass er danach fragt. Zum Beispiel könnte der Editor Engpässe in Rot anzeigen, wenn der Programmierer den Quellcode bearbeitet. Ein anderer Ansatz wäre es, irgendwie darzustellen, was in laufenden Programmen passiert. Das wäre ein besonders großer Gewinn bei serverseitigen Anwendungen, wo es viele laufende Programme zu betrachten gibt. Ein aktiver Profiler könnte grafisch zeigen, was im Speicher passiert, während ein Programm läuft, oder sogar Geräusche machen, die angeben, was passiert.

Geräusche sind ein guter Hinweis auf Probleme. An einem Ort, an dem ich gearbeitet habe, hatten wir eine große Tafel mit Zeigerinstrumenten, die zeigten, was mit unseren Webservern passierte. Die Zeiger wurden von kleinen Servomotoren bewegt, die ein leichtes Geräusch machten, wenn sie sich drehten. Ich konnte die Tafel von meinem Schreibtisch aus nicht sehen, aber ich fand heraus, 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. Ich wäre nicht überrascht, wenn bestimmte Muster des Speicherzugriffs sich als sichere Anzeichen für schlechte Algorithmen erweisen würden. Wenn es einen kleinen Kerl gäbe, der in dem Computer herumläuft und unsere Programme ausführt, hätte er wahrscheinlich genauso eine lange und klagende Geschichte über seinen Job wie ein Bundesangestellter. Oft habe ich das Gefühl, dass ich den Prozessor auf eine Menge Irrwege schicke, aber ich hatte nie eine gute Möglichkeit, zu sehen, was er tut.

Eine Reihe von Lisps kompilieren jetzt in Bytecode, der dann von einem Interpreter ausgeführt wird. Dies wird normalerweise getan, um die Implementierung portabler zu machen, aber es könnte auch ein nützliches Sprachmerkmal sein. Es wäre vielleicht eine gute Idee, den Bytecode zu einem offiziellen Teil der Sprache zu machen und Programmierern zu erlauben, in Engpässen inline-Bytecode zu verwenden. Dann wären solche Optimierungen auch portabel.

Die Natur der Geschwindigkeit, wie sie vom Endnutzer wahrgenommen wird, könnte sich ändern. Mit dem Aufkommen von serverbasierter Software werden immer mehr Programme i/o-gebunden sein. Es wird sich lohnen, i/o schnell zu machen. Die Sprache kann mit einfachen Maßnahmen wie einfachen, schnellen, formatierten Ausgabefunktionen helfen, aber auch mit tiefgreifenden strukturellen Änderungen wie Caching und persistenten Objekten.

Benutzer interessieren sich für Antwortzeiten. Aber eine andere Art von Effizienz wird zunehmend wichtig 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 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 in den meisten Endnutzeranwendungen keine große Rolle. Entwickler konnten davon ausgehen, dass jeder Benutzer einen immer leistungsfähigeren Prozessor auf seinem Schreibtisch hat. Und nach dem Gesetz von Parkinson hat sich die Software so weit ausgedehnt, dass sie die verfügbaren Ressourcen nutzt. Das wird sich mit serverbasierter Software ändern. In dieser Welt werden Hardware und Software zusammen bereitgestellt. Für Unternehmen, die serverbasierte Anwendungen anbieten, wird es einen sehr großen Unterschied für den Gewinn machen, wie viele Benutzer sie pro Server unterstützen können.

In manchen Anwendungen wird der Prozessor der begrenzende Faktor sein und die Ausführungsgeschwindigkeit das Wichtigste, was es zu optimieren gilt. Aber oft wird der Speicher die Grenze sein; die Anzahl der gleichzeitigen Benutzer wird durch die Menge an Speicher bestimmt, die für die Daten jedes Benutzers benötigt wird. Die Sprache kann auch hier helfen. Eine 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 das Lazy Loading zu haben.

9 Zeit

Das letzte Zutaten, die eine populäre Sprache braucht, ist Zeit. Niemand möchte Programme in einer Sprache schreiben, die möglicherweise wieder verschwindet, wie so viele Programmiersprachen es tun. Daher werden die meisten Hacker erst dann in Betracht ziehen, eine Sprache zu verwenden, wenn sie schon ein paar Jahre lang existiert.

Erfinder wunderbarer neuer Dinge sind oft überrascht zu entdecken, dass man Zeit braucht, um eine Botschaft an die Leute zu bringen. Ein Freund von mir tut selten etwas beim ersten Mal, wenn jemand ihn darum bittet. Er weiß, dass Leute manchmal um Dinge bitten, die sich am Ende als unerwünscht herausstellen. Um seine Zeit nicht zu verschwenden, wartet er, bis er zum dritten oder vierten Mal um etwas gebeten wird; dann sind diejenigen, die ihn um etwas bitten, vielleicht ziemlich genervt, aber zumindest wollen sie wahrscheinlich wirklich, was auch immer sie wollen.

Die meisten Leute haben gelernt, eine ähnliche Art von Filterung bei neuen Dingen anzuwenden, von denen sie hören. Sie fangen erst an, darauf zu achten, wenn sie etwas zehnmal gehört haben. Das ist durchaus gerechtfertigt: Die Mehrheit der heißen neuen Dinge erweist sich letztendlich als Zeitverschwendung und verschwindet wieder. Indem ich das Lernen von VRML verzögert habe, habe ich es vermieden, es überhaupt lernen zu müssen.

Daher muss sich jeder, der etwas Neues erfindet, darauf einstellen, seine Botschaft jahrelang zu wiederholen, bevor die Leute anfangen, sie zu verstehen. Wir haben, soweit ich weiß, die erste webserver-basierte Anwendung geschrieben, und es hat Jahre gedauert, bis die Leute verstanden haben, dass sie nicht heruntergeladen werden muss. Das lag nicht daran, dass sie dumm waren. Sie hatten uns einfach ausgeblendet.

Die gute Nachricht ist, dass einfache Wiederholung das Problem löst. Alles, was man tun muss, ist, seine Geschichte immer wieder zu erzählen, und irgendwann werden die Leute anfangen, zuzuhören. Entscheidend ist nicht, wann die Leute bemerken, dass man da ist, sondern wann sie bemerken, dass man immer noch da ist.

Es ist gut, dass es normalerweise eine Weile dauert, Schwung aufzunehmen. Die meisten Technologien entwickeln sich stark weiter, auch nachdem sie erstmals auf den Markt gekommen sind - insbesondere Programmiersprachen. Nichts könnte für eine neue Technologie besser sein als ein paar Jahre, in denen sie nur von einer kleinen Zahl von Vorreitern genutzt wird. Vorreiter sind anspruchsvoll und fordernd und bringen schnell alle verbleibenden Mängel in Ihrer Technologie ans Licht. Wenn man nur wenige Nutzer hat, kann man mit ihnen allen in engem Kontakt stehen. Und Vorreiter sind nachsichtig, wenn man sein System verbessert, auch wenn das zu einigen Brüchen führt.

Es gibt zwei Wege, wie neue Technologie eingeführt wird: die organische Wachstumsmethode und die Big-Bang-Methode. Die organische Wachstumsmethode wird exemplarisch durch den klassischen Garage-Startup ohne Finanzierung dargestellt. Ein paar Jungs entwickeln in der Verborgenheit eine neue Technologie. Sie bringen sie ohne Marketing auf den Markt und haben zunächst nur wenige (fanatisch ergebene) Nutzer. Sie verbessern die Technologie weiter, und inzwischen wächst ihre Nutzerbasis durch Mundpropaganda. Bevor sie sich versehen, sind sie groß.

Der andere Ansatz, die Big-Bang-Methode, wird durch den von Risikokapitalgebern finanzierten, stark vermarkteten Startup verkörpert. Sie eilen, ein Produkt zu entwickeln, bringen es mit großer Publicity auf den Markt und haben sofort (so hoffen sie) eine große Nutzerbasis.

Im Allgemeinen beneiden die Garage-Jungs die Big-Bang-Jungs. Die Big-Bang-Jungs sind glatt und selbstbewusst und werden von den Risikokapitalgebern respektiert. Sie können sich das Beste von allem leisten, und die PR-Kampagne rund um den Start hat den Nebeneffekt, dass sie zu Prominenten werden. Die Jungs vom organischen Wachstum, die in ihrer Garage sitzen, fühlen sich arm und ungeliebt. Und doch denke ich, dass sie oft zu Unrecht Mitleid mit sich selbten haben. Organisches Wachstum scheint bessere Technologie und reichere Gründer hervorzubringen als die Big-Bang-Methode. Wenn man sich die dominierenden Technologien heute 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 gesponserten Forschung. Multics und Common Lisp waren Big-Bang-Projekte, und Unix und MacLisp waren Projekte mit organischem Wachstum.

10 Überarbeitung

"Das Beste an Schreiben ist Überarbeiten", schrieb E. B. White. Jeder gute Schriftsteller weiß das, und das gilt auch für Software. Der wichtigste Teil des Designs ist die Überarbeitung. Programmiersprachen werden, vor allem, nicht oft genug überarbeitet.

Um gute Software zu schreiben, musst du gleichzeitig zwei gegensätzliche Ideen im Kopf behalten. Du brauchst den naiven Glauben des jungen Hackers an seine Fähigkeiten und gleichzeitig den Skeptizismus des Veteranen. Du musst in der Lage sein, mit einer Hälfte deines Gehirns zu denken wie schwer kann es sein?, während du mit der anderen denkst es wird nie funktionieren.

Der Trick ist zu erkennen, dass es hier keinen wirklichen Widerspruch gibt. Du musst optimistisch und skeptisch in Bezug auf zwei verschiedene Dinge sein. Du musst optimistisch in Bezug auf die Möglichkeit sein, das Problem zu lösen, aber skeptisch in Bezug auf den Wert der Lösung, die du bisher hast.

Menschen, die gute Arbeit leisten, denken oft, dass das, woran sie gerade arbeiten, nichts taugt. Andere sehen, was sie getan haben, und sind voller Bewunderung, aber der Schöpfer ist voller Sorge. Dieses Muster ist kein Zufall: Es ist die Sorge, die die Arbeit gut gemacht hat.

Wenn du Hoffnung und Sorge im Gleichgewicht halten kannst, werden sie einen Projektfortschritt vorantreiben, so wie deine beiden Beine ein Fahrrad vorwärts treiben. In der ersten Phase des zweizyklischen Innovationsmotor arbeitest du fieberhaft an einem Problem, inspiriert von deiner Zuversicht, es lösen zu können. In der zweiten Phase betrachtest du, was du getan hast, im Licht des kalten Morgens und siehst all seine Mängel sehr deutlich. Aber solange dein kritischer Geist deine Hoffnung nicht überwiegt, wirst du in der Lage sein, auf dein zweifellos unvollständiges System zu blicken und zu denken: Wie schwer kann es sein, den Rest zu schaffen?, und so den Zyklus fortsetzen.

Es ist schwierig, die beiden Kräfte im Gleichgewicht zu halten. Bei jungen Hackern überwiegt der Optimismus. Sie bringen etwas hervor, sind davon überzeugt, dass es großartig ist, und verbessern es nie. Bei alten Hackern überwiegt der Skeptizismus, und sie wagen es nicht einmal, ehrgeizige Projekte in Angriff zu nehmen.

Alles, was du tun kannst, um den Redesign-Zyklus am Laufen zu halten, ist gut. Prosa kann immer wieder umgeschrieben werden, bis du zufrieden bist. Aber Software wird in der Regel nicht genug umgestaltet. Prosa hat Leser, aber Software hat Benutzer. Wenn ein Schriftsteller einen Essay umschreibt, werden die Leser der alten Version wahrscheinlich nicht darüber klagen, dass ihre Gedanken durch neu eingeführte Inkompatibilität gestört wurden.

Benutzer sind ein zweischneidiges Schwert. Sie können dir helfen, deine Sprache zu verbessern, aber sie können dich auch davon abhalten, sie zu verbessern. Wähle deine Benutzer also sorgfältig aus und sei langsam beim Wachstum ihrer Zahl. Benutzer zu haben, ist wie Optimierung: Der weise Weg ist es, sie zu verzögern. Außerdem kannst du im Allgemeinen zu jedem Zeitpunkt mehr ändern, als du denkst. Veränderungen einzuführen ist wie ein Pflaster abzuziehen: Der Schmerz ist fast so schnell vergessen, wie du ihn gespürt hast.

Jeder weiß, dass es keine gute Idee ist, eine Sprache von einem Ausschuss entwerfen zu lassen. Ausschüsse führen zu schlechtem Design. Aber ich denke, die größte Gefahr von Ausschüssen ist, dass sie die Umgestaltung behindern. Es ist so viel Arbeit, Änderungen einzuführen, dass niemand sich die Mühe machen will. Was ein Ausschuss auch beschließt, bleibt in der Regel so, auch wenn die meisten Mitglieder es nicht mögen.

Selbst ein Ausschuss von zwei Personen steht der Umgestaltung im Weg. Dies passiert besonders bei den Schnittstellen zwischen Softwareteilen, die von zwei verschiedenen Personen geschrieben wurden. Um die Schnittstelle zu ändern, müssen beide gleichzeitig zustimmen, sie zu ändern. Und so ändern sich Schnittstellen oft überhaupt nicht, was ein Problem ist, da sie tendenziell einer der am meisten ad-hoc-Teile eines Systems sind.

Eine mögliche Lösung wäre es, Systeme so zu entwerfen, dass die Schnittstellen horizontal statt vertikal sind - so dass Module immer vertikal geschichtete Abstraktionsschichten sind. Dann wird die Schnittstelle tendenziell von einer von ihnen besessen. Die untere von zwei Ebenen wird entweder eine Sprache sein, in der die obere geschrieben ist, in welchem Fall die untere Ebene die Schnittstelle besitzt, oder sie wird ein Sklave sein, in welchem Fall die Schnittstelle von der oberen Ebene diktiert werden kann.

11 Lisp

All dies impliziert, dass es Hoffnung für ein neues Lisp gibt. Es gibt Hoffnung für jede Sprache, die Hacker das gibt, was sie wollen, einschließlich Lisp. Ich denke, wir haben möglicherweise einen Fehler gemacht, indem wir annahmen, dass Hacker von Lisps Fremdartigkeit abgeschreckt werden. Diese beruhigende Illusion hat uns vielleicht daran gehindert, das eigentliche Problem mit Lisp oder zumindest mit Common Lisp zu erkennen, nämlich dass es für das, was Hacker tun wollen, ungeeignet ist. Eine Hackersprache braucht leistungsfähige Bibliotheken und etwas zum Hacken. Common Lisp hat beides nicht. Eine Hackersprache ist prägnant und hackbar. Common Lisp ist es nicht.

Die gute Nachricht ist, dass es nicht Lisp ist, das ungeeignet ist, sondern Common Lisp. Wenn wir ein neues Lisp entwickeln können, das eine echte Hackersprache ist, denke ich, dass Hacker es benutzen werden. Sie werden jede Sprache benutzen, die den Job besser macht. Alles, was wir tun müssen, ist sicherzustellen, dass dieses neue Lisp einen wichtigen Job besser erledigt als andere Sprachen.

Die Geschichte bietet etwas 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 du entwickelt hast, 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, dass es ein guter Marketingtrick wäre, es als eine 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 offizieller Lebenslauf vermeidet es sorgfältig, das L-Wort zu erwähnen. Aber meine Vermutung ist, dass wir uns nicht scheuen sollten, das neue Lisp Lisp zu nennen. Lisp genießt immer noch viel latenten Respekt unter den allerbesten Hackern - denjenigen, die 6.001 belegt und verstanden haben, zum Beispiel. Und das sind die Benutzer, die du gewinnen musst.

In "How to Become a Hacker" beschreibt Eric Raymond Lisp als etwas wie Latein oder Griechisch - eine Sprache, die du als intellektuelle Übung lernen solltest, auch wenn du sie tatsächlich nicht viel benutzen wirst:

Lisp zu lernen lohnt sich wegen der tiefgreifenden Erleuchtungserfahrung, die du haben wirst, wenn du es endlich verstehst; diese Erfahrung wird dich für den Rest deines Lebens zu einem besseren Programmierer machen, auch wenn du Lisp selbst nicht viel benutzt.

Wenn ich Lisp nicht kennen würde, würde mich das zum Nachdenken anregen. Eine Sprache, die mich zu einem besseren Programmierer machen würde, wenn sie überhaupt etwas bedeutet, meint eine Sprache, die besser zum Programmieren wäre. Und das ist in der Tat die Implikation dessen, was Eric sagt.

Solange diese Idee noch herumschwebt, denke ich, werden Hacker auch für ein neues Lisp empfänglich sein, selbst wenn es Lisp genannt wird. Aber dieses Lisp muss eine Hackersprache sein, wie die klassischen Lisps der 1970er Jahre. Es muss prägnant, einfach und hackbar sein. Und es muss leistungsfähige Bibliotheken haben, um das zu tun, was Hacker heute tun wollen.

In Bezug auf Bibliotheken denke ich, dass es Möglichkeiten gibt, Sprachen wie Perl und Python bei ihrem eigenen Spiel zu schlagen. Viele der neuen Anwendungen, die in den kommenden Jahren geschrieben werden müssen, werden serverseitige Anwendungen sein. Es gibt keinen Grund, warum eine neue Lisp-Sprache keine Zeichenkettenbibliothe-ken haben sollte, die so gut sind wie Perl, und wenn diese neue Lisp-Sprache auch leistungsfähige Bibliotheken für serverseitige Anwendungen hätte, könnte sie sehr beliebt werden. Echte Hacker werden ihre Nasen nicht rümpfen über ein neues Werkzeug, das es ihnen ermöglicht, schwierige Probleme mit ein paar Bibliotheksaufrufen zu lösen. Denken Sie daran, Hacker sind faul.

Es könnte ein noch größerer Gewinn sein, Kernsprachunterstützung für serverseitige Anwendungen zu haben. Zum Beispiel explizite Unterstützung für Programme mit mehreren Benutzern oder Dateneigentum auf der Ebene von Typkennzeichen.

Serverseitige Anwendungen geben uns auch die Antwort auf die Frage, wofür diese neue Lisp-Sprache verwendet werden soll. Es würde nicht schaden, Lisp als Skriptsprache für Unix zu verbessern. (Es wäre schwer, es schlimmer zu machen.) Aber ich denke, es gibt Bereiche, in denen bestehende Sprachen leichter zu besiegen wären. Ich denke, es wäre besser, dem Modell von Tcl zu folgen und die Lisp-Sprache zusammen mit einem vollständigen System zur Unterstützung serverseitiger Anwendungen bereitzustellen. Lisp ist ein natürlicher Fit für serverseitige Anwendungen. Lexikalische Schließungen bieten eine Möglichkeit, die Wirkung von Unterprogrammen zu erzielen, wenn die Benutzeroberfläche nur eine Reihe von Webseiten ist. S-Ausdrücke passen gut zu HTML, und Makros sind gut darin, es zu generieren. Es müssen bessere Werkzeuge zum Schreiben serverseitiger Anwendungen geben, und es muss eine neue Lisp-Sprache geben, und die beiden würden sehr gut zusammenarbeiten.

12 Die Traumsprache

Lassen Sie uns versuchen, die Traumsprache des Hackers zusammenzufassen. Die Traumsprache ist schön, sauber und prägnant. Sie hat eine interaktive Toplevel-Umgebung, die schnell startet. Sie können Programme zum Lösen gängiger Probleme mit sehr wenig Code schreiben. Nahezu der gesamte Code in jedem Programm, das Sie schreiben, ist Code, der für Ihre Anwendung spezifisch ist. Alles andere wurde für Sie erledigt.

Die Syntax der Sprache ist knapp bis zur Fehlergrenze. Sie müssen nie ein unnötiges Zeichen eingeben, und Sie müssen sogar die Umschalttaste nicht oft benutzen.

Mit Hilfe großer 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 sollten. Sie können Innenschleifen blitzschnell machen, sogar durch Schreiben von Inline-Bytecode, wenn Sie müssen.

Es gibt viele gute Beispiele zum Lernen, und die Sprache ist intuitiv genug, dass Sie sie in ein paar Minuten anhand von Beispielen lernen können. Sie müssen nicht oft im Handbuch nachschlagen. Das Handbuch ist dünn und enthält nur wenige Warnungen und Einschränkungen.

Die Sprache hat einen kleinen Kern und leistungsfähige, hochgradig orthogonale Bibliotheken, die genauso sorgfältig entworfen sind wie die Kernsprache. Die Bibliotheken arbeiten alle gut zusammen; alles in der Sprache passt wie die Teile einer feinen Kamera zusammen. Nichts ist veraltet oder wird aus Kompatibilitätsgründen beibehalten. Der Quellcode aller Bibliotheken ist leicht zugänglich. Es ist einfach, mit dem Betriebssystem und mit in anderen Sprachen geschriebenen Anwendungen zu kommunizieren.

Die Sprache ist in Schichten aufgebaut. Die höheren Abstraktionsebenen werden auf sehr transparente Weise aus niedrigeren Abstraktionsebenen aufgebaut, auf die Sie zugreifen können, wenn Sie möchten.

Nichts wird vor Ihnen verborgen, was nicht unbedingt nötig ist. Die Sprache bietet Abstraktionen nur als Möglichkeit, Ihre Arbeit zu erleichtern, anstatt Ihnen vorzuschreiben, was Sie tun sollen. Tatsächlich ermutigt die Sprache Sie, gleichberechtigter Teilnehmer an ihrem Design zu sein. Sie können alles an ihr ä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 kommen, wurden 1964 von Timothy Hart vorgeschlagen, zwei Jahre nachdem Lisp 1.5 veröffentlicht wurde. Was anfangs fehlte, waren Möglichkeiten, Variableneinfang und mehrfache Auswertung zu vermeiden; Harts Beispiele sind beiden Problemen ausgesetzt.

[2] In When the Air Hits Your Brain erzählt der Neurochirurg Frank Vertosick ein Gespräch, in dem sein Oberarzt Gary über den Unterschied zwischen Chirurgen und Internisten ("Flöhe") spricht:

Gary und ich bestellten eine große Pizza und fanden einen offenen Sitzplatz. Der Oberarzt zündete sich eine Zigarette an. "Sieh dir diese verdammten Flöhe an, wie sie über eine Krankheit quatschen, die sie in ihrem Leben vielleicht einmal sehen werden. Das ist das Problem mit den Flöhe, sie mögen nur den bizarren Kram. Sie hassen ihre Brotverdiener-Fälle. Das ist der Unterschied zwischen uns und den verdammten Flöhen. Siehst du, wir lieben große, saftige Bandscheibenvorfälle in der Lendenwirbelsäule, aber sie hassen Bluthochdruck...."

Es ist schwer, sich einen Bandscheibenvorfall in der Lendenwirbelsäule als saftig vorzustellen (außer im wörtlichen Sinne). Und doch glaube ich zu wissen, was sie meinen. Ich habe oft einen saftigen Fehler aufspüren müssen. Jemand, der kein Programmierer ist, würde es schwer finden, sich vorzustellen, dass es Vergnügen an einem Fehler geben könnte. Sicher ist es besser, wenn alles einfach funktioniert. In gewisser Weise ist es das auch. Und doch gibt es unbestreitbar eine düstere Befriedigung darin, bestimmte Arten von Fehlern aufzuspüren.