BELIEBT SEIN
OriginalMai 2001
(Dieser Artikel wurde als eine Art Businessplan für eine neue Sprache geschrieben. Daher fehlt (weil es als selbstverständlich angenommen wird) das wichtigste Merkmal einer guten Programmiersprache: sehr mächtige Abstraktionen.)
Ein Freund von mir erzählte einmal einem bedeutenden Betriebssystem- Experten, dass er eine wirklich gute Programmiersprache entwerfen wollte. Der Experte sagte ihm, dass es eine Verschwendung von Zeit wäre, dass Programmiersprachen nicht beliebt oder unbeliebt werden, basierend auf ihren Vorzügen, und so würde niemand seine Sprache benutzen, egal wie gut sie wäre. Zumindest war das passiert, was mit der Sprache passiert war, die er entworfen hatte.
Was macht eine Sprache beliebt? Verdienen beliebte Sprachen ihre Popularität? Lohnt es sich, zu versuchen, eine gute Programmiersprache zu definieren? Wie würdest du das tun?
Ich denke, die Antworten auf diese Fragen lassen sich finden, indem man sich Hacker anschaut und lernt, was sie wollen. Programmier- sprachen sind für Hacker, und eine Programmiersprache ist gut als Programmiersprache (und nicht etwa als Übung in denotationaler Semantik oder Compiler-Design) genau dann, wenn Hacker sie mögen.
1 Die Mechanik der Popularität
Es stimmt natürlich, dass die meisten Leute Programmiersprachen nicht einfach aufgrund ihrer Vorzüge wählen. Die meisten Programmierer werden von jemand anderem gesagt, welche Sprache sie verwenden sollen. Und doch denke ich, dass der Einfluss solcher externen Faktoren auf die Popularität von Programmiersprachen nicht so groß ist, wie man manchmal denkt. Ich denke, ein größeres Problem ist, dass die Vorstellung eines Hackers von einer guten Programmiersprache nicht die gleiche 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 den menschlichen Stärken und Schwächen entsprechen, so wie Schuhe für menschliche Füße konzipiert sein müssen. Wenn ein Schuh drückt, wenn man ihn anzieht, ist es ein schlechter Schuh, wie elegant er auch als Skulptur sein mag.
Es kann sein, dass die Mehrheit der Programmierer eine gute Sprache nicht von einer schlechten unterscheiden kann. Aber das ist bei jedem anderen Werkzeug nicht anders. Das bedeutet nicht, dass es eine Verschwendung von Zeit ist, zu versuchen, eine gute Sprache zu entwerfen. Experten-Hacker können eine gute Sprache erkennen, wenn sie eine sehen, und sie werden sie benutzen. Experten-Hacker sind eine winzige Minderheit, zugegebenermaßen, aber diese winzige Minderheit schreibt die gesamte gute Software, und ihr Einfluss ist so groß, dass der Rest der Programmierer dazu neigen wird, die Sprache zu verwenden, die sie verwenden. Oft ist es in der Tat nicht nur Einfluss, sondern Befehl: oft sind die Experten-Hacker die gleichen Leute, die als ihre Chefs oder Fakultätsberater den anderen Programmierern sagen, welche Sprache sie verwenden sollen.
Die Meinung von Experten-Hackern ist nicht die einzige Kraft, die die relative Popularität von Programmiersprachen bestimmt - Legacy-Software (Cobol) und Hype (Ada, Java) spielen ebenfalls eine Rolle - aber ich denke, es ist die mächtigste Kraft über lange Zeit. Angenommen, es gibt eine ursprüngliche kritische Masse und genügend Zeit, wird eine Programmiersprache wahrscheinlich so beliebt, wie sie es verdient. Und Popularität trennt gute Sprachen weiter von schlechten, weil Feedback von echten Nutzern immer zu Verbesserungen führt. Schauen Sie sich an, wie sehr sich jede beliebte Sprache während ihres Lebens verändert hat. Perl und Fortran sind extreme Fälle, aber selbst Lisp hat sich stark verändert. Lisp 1.5 hatte zum Beispiel keine Makros; diese entwickelten sich später, nachdem Hacker am MIT ein paar Jahre damit verbracht hatten, Lisp zu verwenden, um echte Programme zu schreiben. [1]
Ob eine Sprache nun gut sein muss, um beliebt zu sein, ich denke, eine Sprache muss beliebt sein, um gut zu sein. Und sie muss beliebt bleiben, um gut zu bleiben. Der Stand der Technik in Programmiersprachen steht nicht still. Und doch sind die Lisps, die wir heute haben, immer noch im Wesentlichen das, was sie Mitte der 1980er Jahre am MIT hatten, weil das das letzte Mal war, dass Lisp eine ausreichend große und anspruchsvolle Benutzerbasis hatte.
Natürlich müssen Hacker von einer Sprache wissen, bevor sie sie verwenden können. Wie sollen sie davon hören? Von anderen Hackern. Aber es muss eine anfängliche Gruppe von Hackern geben, die die Sprache verwenden, damit andere überhaupt davon hören. Ich frage mich, wie groß diese Gruppe sein muss; wie viele Benutzer bilden eine kritische Masse? Aus dem Stegreif würde ich sagen, zwanzig. Wenn eine Sprache zwanzig verschiedene Benutzer hätte, das heißt zwanzig Benutzer, die sich unabhängig voneinander entschieden haben, sie zu verwenden, würde ich sie für real halten.
Dorthin zu gelangen kann nicht einfach sein. Ich wäre nicht überrascht, wenn es schwieriger ist, von null auf zwanzig zu kommen als von zwanzig auf tausend. Der beste Weg, um diese ersten zwanzig Benutzer 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
Beginnen wir damit, einen externen Faktor anzuerkennen, der die Popularität einer Programmiersprache beeinflusst. Um beliebt zu werden, muss eine Programmiersprache die Skriptsprache eines beliebten 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 sollen die Skriptsprachen von Webbrowsern sein.
Lisp ist keine massenhaft beliebte Sprache, weil sie nicht die Skriptsprache eines massenhaft beliebten Systems ist. Die Popularität, die sie bewahrt, stammt aus den 1960er und 1970er Jahren, als sie die Skriptsprache des MIT war. Viele der großen Programmierer der damaligen Zeit waren irgendwann mit dem MIT verbunden. Und in den frühen 1970er Jahren, vor C, war die Lisp-Variante des MIT, genannt MacLisp, eine der wenigen Programmiersprachen, die ein ernsthafter Hacker verwenden wollte.
Heute ist Lisp die Skriptsprache von zwei mäßig beliebten Systemen, Emacs und Autocad, und aus diesem Grund vermute ich, dass die meisten Lisp-Programmierungen heute in Emacs Lisp oder AutoLisp erfolgen.
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 sie hacken. Wenn Sie also eine beliebte Sprache entwerfen wollen, müssen Sie entweder mehr als eine Sprache liefern, oder Sie müssen Ihre Sprache so entwerfen, dass sie die Skriptsprache eines bestehenden Systems ersetzt.
Common Lisp ist unbeliebt, zum Teil, weil es eine Waise ist. Es kam ursprünglich mit einem System zum Hacken: der Lisp Machine. Aber Lisp Machines (zusammen mit Parallelrechnern) wurden in den 1980er Jahren von der zunehmenden Leistung von Allzweckprozessoren überrollt. Common Lisp wäre vielleicht beliebt geblieben, wenn es eine gute Skriptsprache für Unix gewesen wäre. Es ist leider eine schrecklich schlechte.
Eine Möglichkeit, diese Situation zu beschreiben, ist zu sagen, dass eine Sprache nicht nach ihren eigenen Vorzügen beurteilt wird. Eine andere Sichtweise ist, dass eine Programmiersprache eigentlich keine Programmiersprache ist, wenn sie nicht auch die Skriptsprache von etwas ist. Dies erscheint nur dann unfair, wenn es eine Überraschung ist. 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 frei sein. Unternehmen werden für Software bezahlen, aber einzelne Hacker nicht, und es sind die Hacker, die Sie anziehen müssen.
Eine Sprache braucht auch ein Buch darüber. Das Buch sollte dünn, gut geschrieben und voller guter Beispiele sein. K&R ist hier das Ideal. Im Moment würde ich fast sagen, dass eine Sprache ein Buch haben muss, das von O'Reilly veröffentlicht wird. Das wird zum Test dafür, ob es für Hacker wichtig ist.
Es sollte auch Online-Dokumentation geben. Tatsächlich kann das Buch als Online-Dokumentation beginnen. Aber ich denke, dass physische Bücher noch nicht überholt sind. Ihr Format ist bequem, und die de facto Zensur, die von Verlagen auferlegt wird, ist ein nützlicher, wenn auch unvollkommener Filter. Buchhandlungen sind einer der wichtigsten Orte, um etwas über neue Sprachen zu lernen.
3 Kürze
Angenommen, Sie können die drei Dinge liefern, die jede Sprache benötigt - eine kostenlose Implementierung, ein Buch und etwas zum Hacken - wie machen Sie eine Sprache, die Hacker mögen?
Eine Sache, die Hacker mögen, ist Kürze. Hacker sind faul, auf die gleiche Weise, wie Mathematiker und modernistische Architekten faul sind: sie hassen alles Überflüssige. Es wäre nicht weit von der Wahrheit entfernt zu sagen, dass ein Hacker, der kurz davor steht, ein Programm zu schreiben, zumindest unbewusst entscheidet, welche Sprache er verwenden soll, basierend auf der Gesamtzahl der Zeichen, die er tippen muss. Wenn das nicht genau so ist, wie Hacker denken, würde ein Sprachdesigner gut daran tun, so zu tun, als wäre es so.
Es ist ein Fehler, zu versuchen, den Benutzer mit langatmigen Ausdrücken zu verwöhnen, die dem Englischen ähneln sollen. Cobol ist berüchtigt für diesen Fehler. Ein Hacker würde es als etwas zwischen einer Beleidigung seiner Intelligenz und einer Sünde gegen Gott ansehen, wenn er gebeten würde, zu schreiben
add x to y giving z
anstatt
z = x+y
Es wurde manchmal gesagt, dass Lisp first und rest anstelle von car und cdr verwenden sollte, weil es Programme leichter lesbar machen würde. Vielleicht für die ersten paar Stunden. Aber ein Hacker kann schnell genug lernen, dass car das erste Element einer Liste bedeutet und cdr den Rest. Die Verwendung von first und rest bedeutet 50 % mehr Tippen. Und sie sind auch unterschiedlich lang, was bedeutet, dass die Argumente nicht übereinstimmen, wenn sie aufgerufen werden, wie es bei car und cdr oft der Fall ist, in aufeinanderfolgenden Zeilen. Ich habe festgestellt, dass es sehr wichtig ist, wie Codezeilen auf der Seite angeordnet sind. 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, an dem stark typisierte Sprachen verlieren. Wenn alles andere gleich ist, möchte niemand ein Programm mit einer Menge von Deklarationen beginnen. Alles, was implizit sein kann, sollte es auch sein.
Die einzelnen Token sollten ebenfalls kurz sein. Perl und Common Lisp befinden sich in dieser Frage an entgegengesetzten Polen. Perl-Programme können fast kryptisch dicht sein, während die Namen der eingebauten Common Lisp-Operatoren komisch lang sind. Die Designer von Common Lisp erwarteten wahrscheinlich, dass Benutzer Texteditoren haben, die diese langen Namen für sie eingeben würden. Aber der Preis für einen langen Namen ist nicht nur der Preis für das Tippen. Es gibt auch den Preis für das Lesen und den Preis für den Platz, den er auf Ihrem Bildschirm einnimmt.
4 Hackbarkeit
Es gibt eine Sache, die für einen Hacker wichtiger ist als Kürze: in der Lage zu sein, das zu tun, was man will. In der Geschichte der Programmiersprachen wurde überraschend viel Aufwand darauf verwendet, Programmierer daran zu hindern, Dinge zu tun, die als unzulässig angesehen werden. Dies ist ein gefährlich anmaßender Plan. Wie kann der Sprachdesigner wissen, was der Programmierer tun muss? Ich denke, Sprachdesigner würden besser daran tun, ihren Zielbenutzer als ein Genie zu betrachten, das Dinge tun muss, die sie sich nie vorgestellt haben, anstatt als einen Tollpatsch, der vor sich selbst geschützt werden muss. Der Tollpatsch wird sich sowieso in den Fuß schießen. Sie können ihn vielleicht davon abhalten, auf Variablen in einem anderen Paket zu verweisen, aber Sie können ihn nicht davon abhalten, ein schlecht gestaltetes 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: zum Beispiel den Zugriff auf die interne Darstellung einer hochrangigen Abstraktion. Hacker mögen es zu hacken, und Hacken bedeutet, in Dinge einzudringen und den ursprünglichen Designer in Frage zu stellen.
Lass dich in Frage stellen. Wenn du ein Werkzeug herstellst, benutzen die Leute es auf eine Weise, die du nicht beabsichtigt hast, und das gilt besonders für ein hochgradig artikuliertes Werkzeug wie eine Programmiersprache. Viele Hacker werden dein semantisches Modell auf eine Weise verändern wollen, die du dir nie vorgestellt hast. Ich sage, lass sie; gib dem Programmierer Zugriff auf so viel internes Zeug wie möglich, ohne Laufzeitsysteme wie den Garbage Collector zu gefährden.
In Common Lisp habe ich oft die Felder einer Struktur durchlaufen wollen - um zum Beispiel Referenzen auf ein gelöschtes Objekt zu durchsuchen oder Felder zu finden, die nicht initialisiert sind. Ich weiß, dass die Strukturen nur Vektoren darunter sind. Und doch kann ich keine allgemeine Funktion schreiben, die ich auf jede Struktur anwenden kann. Ich kann nur auf die Felder mit Namen zugreifen, weil das ist, was eine Struktur bedeuten soll.
Ein Hacker möchte vielleicht nur ein oder zweimal in einem großen Programm das beabsichtigte Modell der Dinge untergraben. Aber was für ein Unterschied es macht, in der Lage zu sein. Und es kann mehr als nur die Frage der Lösung eines Problems sein. Es gibt auch eine Art von Vergnügen hier. Hacker teilen das geheime Vergnügen des Chirurgen, in groben Eingeweiden herumzustochern, das geheime Vergnügen des Teenagers, Pickel auszudrücken. [2] Zumindest für Jungen sind gewisse Arten von Schrecken faszinierend. Das Maxim-Magazin veröffentlicht jährlich einen Band mit Fotografien, der eine Mischung aus Pin-ups und grausamen Unfällen enthält. Sie kennen ihr Publikum.
Historisch gesehen war Lisp gut darin, Hacker ihren Willen zu lassen. Die politische Korrektheit von Common Lisp ist eine Abweichung. Frühe Lisps ließen dich alles in die Hand nehmen. Ein großer Teil dieses Geistes ist glücklicherweise in Makros erhalten geblieben. Was für eine wunderbare Sache, in der Lage zu sein, beliebige Transformationen am Quellcode vorzunehmen.
Klassische Makros sind ein echtes Werkzeug für Hacker – einfach, mächtig und gefährlich. Es ist so einfach zu verstehen, was sie tun: Sie rufen eine Funktion mit den Argumenten des Makros auf, und was immer sie zurückgibt, wird an die Stelle des Makroaufrufs eingefügt. Hygienische Makros verkörpern das entgegengesetzte 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, zu entscheiden, was Programmierer sich wünschen dürfen. Hygienische Makros sollen mich unter anderem vor Variablenfang schützen, aber Variablenfang ist genau das, was ich in einigen Makros möchte.
Eine wirklich gute Sprache sollte sowohl sauber als auch schmutzig sein: sauber entworfen, mit einem kleinen Kern aus gut verstandenen und hoch orthogonalen Operatoren, aber schmutzig in dem Sinne, dass sie Hackern erlaubt, ihren Willen mit ihr zu tun. C ist so. So waren auch die frühen Lisps. Eine echte Hackersprache wird immer einen leicht schmuddeligen Charakter haben.
Eine gute Programmiersprache sollte Funktionen haben, die die Art von Leuten, die den Ausdruck "Software Engineering" verwenden, kopfschüttelnd missbilligen lassen. Am anderen Ende des Kontinuums stehen Sprachen wie Ada und Pascal, Modelle der Anständigkeit, die gut zum Unterrichten geeignet sind und nicht viel mehr.
5 Wegwerfprogramme
Um für Hacker attraktiv zu sein, muss eine Sprache gut geeignet sein, um die Art von Programmen zu schreiben, die sie schreiben wollen. Und das bedeutet, vielleicht überraschend, dass sie gut geeignet sein muss, um Wegwerfprogramme zu schreiben.
Ein Wegwerfprogramm ist ein Programm, das Sie schnell für eine begrenzte Aufgabe schreiben: ein Programm, um eine Systemadministrationsaufgabe zu automatisieren, oder um Testdaten für eine Simulation zu generieren, oder um Daten von einem Format in ein anderes zu konvertieren. Das Überraschende an Wegwerfprogrammen ist, dass sie, wie die "temporären" 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 eine Ahnung, dass die besten großen Programme so beginnen, anstatt von Anfang an groß entworfen zu werden, wie der Hoover Dam. Es ist erschreckend, etwas Großes von Grund auf neu zu bauen. Wenn Menschen ein Projekt übernehmen, das zu groß ist, werden sie überfordert. Das Projekt wird entweder festgefahren, oder das Ergebnis ist steril und hölzern: ein Einkaufszentrum statt einer echten Innenstadt, Brasília statt Rom, Ada statt C.
Eine andere Möglichkeit, ein großes Programm zu erhalten, ist, mit einem Wegwerfprogramm zu beginnen und es immer weiter zu verbessern. Dieser Ansatz ist weniger entmutigend, und das Design des Programms profitiert von der Evolution. Ich denke, wenn man nachschauen würde, 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 zuerst geschrieben wurden, weil es selten vorkommt, dass ein Programm portiert wird, außer aus politischen Gründen. Und so muss man, paradoxerweise, wenn man eine Sprache schaffen will, die für große Systeme verwendet wird, sie gut für das Schreiben von Wegwerfprogrammen machen, denn dort kommen große Systeme her.
Perl ist ein markantes Beispiel für diese Idee. Es wurde nicht nur für das Schreiben von Wegwerfprogrammen entwickelt, sondern war selbst so ziemlich ein Wegwerfprogramm. Perl begann als eine Sammlung von Dienstprogrammen zur Generierung von Berichten und entwickelte sich erst zu einer Programmiersprache, als die Wegwerfprogramme, die die Leute darin schrieben, größer wurden. Erst mit Perl 5 (wenn überhaupt) war die Sprache geeignet, um ernsthafte Programme zu schreiben, und dennoch war sie bereits enorm beliebt.
Was macht eine Sprache gut für Wegwerfprogramme? Zunächst einmal muss sie leicht verfügbar sein. Ein Wegwerfprogramm ist etwas, von dem man erwartet, dass man es in einer Stunde schreibt. Daher muss die Sprache wahrscheinlich bereits auf dem Computer installiert sein, den Sie verwenden. Es kann nicht etwas sein, das Sie installieren müssen, bevor Sie es verwenden. Es muss da sein. C war da, weil es mit dem Betriebssystem kam. Perl war da, weil es ursprünglich ein Werkzeug für Systemadministratoren war, und Ihrer hatte es bereits installiert.
Verfügbar zu sein bedeutet jedoch mehr als 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.
Eine weitere Sache, die Sie in einem Wegwerfprogramm wollen, ist Kürze. Kürze ist für Hacker immer attraktiv, und das gilt besonders für ein Programm, von dem sie erwarten, dass es in einer Stunde fertig ist.
6 Bibliotheken
Das Ultimative an Kürze ist natürlich, das Programm bereits für Sie geschrieben zu haben und es einfach nur aufzurufen. Und das bringt uns zu dem, was meiner Meinung nach ein immer wichtigeres Merkmal von Programmiersprachen sein wird: Bibliotheksfunktionen. Perl gewinnt, weil es große Bibliotheken zur Manipulation von Zeichenketten hat. Diese Klasse von Bibliotheksfunktionen ist besonders wichtig für Wegwerfprogramme, die oft ursprünglich zum Konvertieren oder Extrahieren von Daten geschrieben werden. Viele Perl-Programme beginnen wahrscheinlich nur mit ein paar Bibliotheksaufrufen, die aneinandergereiht sind.
Ich denke, dass viele der Fortschritte, die in den nächsten fünfzig Jahren in Programmiersprachen erzielt werden, mit Bibliotheksfunktionen zu tun haben werden. Ich denke, dass zukünftige Programmiersprachen Bibliotheken haben werden, die so sorgfältig entworfen sind wie die Kernsprache. Programmiersprachen-Design wird nicht mehr darum gehen, ob man seine Sprache stark oder schwach typisiert, oder objektorientiert, oder funktional, oder was auch immer, sondern darum, wie man großartige Bibliotheken entwirft. Die Art von Sprachdesignern, die gerne darüber nachdenken, wie man Typsysteme entwirft, könnten bei diesem Gedanken erschauern. Es ist fast so, als würde man Anwendungen schreiben! Schade. Sprachen sind für Programmierer da, und Bibliotheken sind das, was Programmierer brauchen.
Es ist schwer, gute Bibliotheken zu entwerfen. Es ist nicht einfach eine Frage des Schreibens von viel Code. Wenn die Bibliotheken zu groß werden, kann es manchmal länger dauern, die Funktion zu finden, die Sie brauchen, 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 versagt. Es gibt nur rudimentäre Bibliotheken zur Manipulation von Zeichenketten und fast keine zum Sprechen mit dem Betriebssystem. Aus historischen Gründen versucht Common Lisp, so zu tun, als ob das Betriebssystem nicht existiert. Und weil man nicht mit dem Betriebssystem sprechen kann, ist es unwahrscheinlich, dass man ein ernsthaftes Programm schreiben kann, das nur die eingebauten Operatoren in Common Lisp verwendet. Man muss auch einige implementationsspezifische Hacks verwenden, und in der Praxis neigen diese dazu, nicht alles zu liefern, was man sich wünscht. Hacker würden Lisp viel höher schätzen, wenn Common Lisp über leistungsstarke Zeichenkettenbibliotheken und gute Betriebssystemunterstützung verfügen würde.
7 Syntax
Könnte eine Sprache mit Lisps Syntax, oder genauer gesagt, dem Mangel an Syntax, jemals populär werden? Ich kenne die Antwort auf diese Frage nicht. Ich denke, dass Syntax nicht der Hauptgrund dafür ist, dass Lisp derzeit nicht beliebt ist. Common Lisp hat schlimmere Probleme als eine ungewohnte Syntax. Ich kenne mehrere Programmierer, die mit Präfix-Syntax vertraut sind und dennoch standardmäßig Perl verwenden, weil es leistungsstarke Zeichenkettenbibliotheken hat und mit dem Betriebssystem sprechen kann.
Es gibt zwei mögliche Probleme mit Präfix-Notation: dass sie für Programmierer ungewohnt ist und dass sie nicht dicht genug ist. Die konventionelle Weisheit in der Lisp-Welt ist, dass das erste Problem das eigentliche ist. Ich bin mir da nicht so sicher. Ja, Präfix-Notation lässt normale Programmierer in Panik geraten. Aber ich glaube nicht, dass die Meinung normaler Programmierer eine Rolle spielt. Sprachen werden populär oder unbeliebt, je nachdem, was erfahrene Hacker von ihnen halten, und ich denke, dass erfahrene Hacker mit Präfix-Notation umgehen können. Perl-Syntax kann ziemlich unverständlich sein, aber das hat der Popularität von Perl nicht im Wege gestanden. Wenn überhaupt, hat es vielleicht dazu beigetragen, einen Perl-Kult zu fördern.
Ein ernsteres Problem ist die Diffusität der Präfix-Notation. Für erfahrene Hacker ist das wirklich ein Problem. Niemand möchte (aref a x y) schreiben, wenn er a[x,y] schreiben könnte.
In diesem speziellen Fall gibt es eine Möglichkeit, uns aus dem Problem herauszuwinden. Wenn wir Datenstrukturen so behandeln, als wären sie Funktionen auf Indizes, könnten wir stattdessen (a x y) schreiben, was sogar 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 bedeutsam machen. So lesen Programmierer Code sowieso: Wenn Einrückungen etwas aussagen und Begrenzer etwas anderes, dann gehen wir nach den Einrückungen. Einrückungen als bedeutsam zu behandeln, würde diese häufige Fehlerquelle beseitigen und Programme kürzer machen.
Manchmal ist Infix-Syntax leichter zu lesen. Das gilt besonders für mathematische Ausdrücke. Ich benutze Lisp mein ganzes Programmiererleben und finde Präfix-Mathematische Ausdrücke immer noch nicht natürlich. Und doch ist es bequem, besonders wenn man Code generiert, Operatoren zu haben, die eine beliebige Anzahl von Argumenten annehmen. Wenn wir also Infix-Syntax haben, sollte sie wahrscheinlich als eine Art Read-Makro implementiert werden.
Ich glaube nicht, dass wir religiös dagegen sein sollten, Syntax in Lisp einzuführen, solange sie sich auf eine gut verstandene Weise in zugrunde liegende S-Ausdrücke übersetzt. Es gibt bereits eine ganze Menge Syntax in Lisp. Es ist nicht unbedingt schlecht, mehr einzuführen, solange niemand gezwungen ist, sie zu verwenden. In Common Lisp sind einige Begrenzer für die Sprache reserviert, was darauf hindeutet, dass zumindest einige der Designer beabsichtigten, in Zukunft mehr Syntax zu haben.
Eines der eklatantesten unlispy-Syntaxelemente in Common Lisp findet sich in Formatstrings; format ist eine eigene Sprache, und diese Sprache ist nicht Lisp. Wenn es einen Plan gäbe, mehr Syntax in Lisp einzuführen, könnten Format-Spezifizierer darin aufgenommen werden. Es wäre eine gute Sache, wenn Makros Format-Spezifizierer so generieren könnten, wie sie jede andere Art von Code generieren.
Ein prominenter Lisp-Hacker erzählte mir, dass sein Exemplar von CLTL sich immer im Abschnitt format öffnet. Meins auch. Das deutet wahrscheinlich auf Verbesserungspotenzial hin. Es könnte auch bedeuten, dass Programme viel E/A betreiben.
8 Effizienz
Eine gute Sprache sollte, wie jeder weiß, schnellen Code generieren. Aber in der Praxis glaube ich nicht, dass schneller Code in erster Linie von Dingen kommt, die man beim Design der Sprache tut. Wie Knuth vor langer Zeit feststellte, spielt Geschwindigkeit nur in bestimmten kritischen Engpässen eine Rolle. Und wie viele Programmierer seitdem festgestellt haben, irrt man sich sehr oft darüber, wo diese Engpässe liegen.
In der Praxis ist der Weg zu schnellem Code also eher ein sehr guter Profiler als zum Beispiel die starke Typisierung der Sprache. Sie müssen nicht den Typ jedes Arguments in jedem Aufruf im Programm kennen. Sie müssen jedoch in der Lage sein, die Typen von Argumenten in den Engpässen zu deklarieren. Und noch mehr müssen Sie in der Lage sein, herauszufinden, wo die Engpässe liegen.
Ein Kritikpunkt, den Leute an Lisp hatten, ist, dass es schwer zu sagen ist, was teuer ist. Das könnte stimmen. Es könnte auch unvermeidlich sein, wenn man eine sehr abstrakte Sprache haben möchte. Und in jedem Fall denke ich, dass ein gutes Profiling einen großen Beitrag zur Behebung des Problems leisten würde: Man würde schnell lernen, was teuer ist.
Ein Teil des Problems ist hier sozial. Sprachdesigner schreiben gerne schnelle Compiler. So messen sie ihre Fähigkeiten. Sie betrachten den Profiler bestenfalls als Add-on. Aber in der Praxis kann ein guter Profiler mehr dazu beitragen, die Geschwindigkeit von tatsächlich in der Sprache geschriebenen Programmen zu verbessern, als ein Compiler, der schnellen Code generiert. Auch hier sind Sprachdesigner etwas von ihren Benutzern abgekoppelt. Sie leisten wirklich gute Arbeit, um ein leicht falsches Problem zu lösen.
Es könnte eine gute Idee sein, einen aktiven Profiler zu haben – um Leistungsdaten an den Programmierer zu pushen, anstatt darauf zu warten, dass er danach fragt. Zum Beispiel könnte der Editor Engpässe rot anzeigen, wenn der Programmierer den Quellcode bearbeitet. Ein anderer Ansatz wäre, das Geschehen in laufenden Programmen irgendwie darzustellen. Dies wäre ein besonders großer Gewinn bei serverseitigen Anwendungen, bei denen man viele laufende Programme betrachten kann. Ein aktiver Profiler könnte grafisch darstellen, was im Speicher passiert, während ein Programm läuft, oder sogar Geräusche erzeugen, die anzeigen, was passiert.
Sound ist ein guter Hinweis auf Probleme. An einem Ort, an dem ich gearbeitet habe, hatten wir eine große Tafel mit Zifferblättern, die zeigten, was mit unseren Webservern geschah. Die Zeiger wurden von kleinen Servomotoren bewegt, die beim Drehen ein leichtes Geräusch machten. Ich konnte die Tafel von meinem Schreibtisch aus 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 automatisch ineffiziente Algorithmen erkennt. Ich wäre nicht überrascht, wenn sich bestimmte Muster des Speicherzugriffs als sichere Anzeichen für schlechte Algorithmen herausstellen würden. Wenn es einen kleinen Kerl gäbe, der im Computer herumläuft und unsere Programme ausführt, hätte er wahrscheinlich eine ebenso lange und klagende Geschichte über seinen Job zu erzählen wie ein Angestellter der Bundesregierung. Ich habe oft das Gefühl, dass ich den Prozessor auf viele wilde Gänsejagden schicke, aber ich hatte noch nie eine gute Möglichkeit, mir anzusehen, was er tut.
Eine Reihe von Lisps kompilieren jetzt in Bytecode, der dann von einem Interpreter ausgeführt wird. Dies wird in der Regel getan, um die Implementierung leichter portierbar zu machen, aber es könnte ein nützliches Sprachmerkmal sein. Es könnte eine gute Idee sein, 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 portabel.
Die Natur der Geschwindigkeit, wie sie vom Endbenutzer wahrgenommen wird, könnte sich ändern. Mit dem Aufkommen serverseitiger Anwendungen werden immer mehr Programme sich als E/A-gebunden herausstellen. Es wird sich lohnen, E/A zu beschleunigen. Die Sprache kann mit einfachen Maßnahmen wie einfachen, schnellen, formatierten Ausgabefunktionen helfen, und auch mit tiefgreifenden strukturellen Änderungen wie Caching und persistenten Objekten.
Benutzer interessieren sich für die Antwortzeit. Aber eine andere Art von Effizienz wird zunehmend wichtig: die Anzahl der gleichzeitigen Benutzer die Sie pro Prozessor unterstützen können. Viele der interessanten Anwendungen die in naher Zukunft geschrieben werden, werden serverseitig sein, und die Anzahl der Benutzer pro Server ist die entscheidende Frage für jeden, der solche Anwendungen hostet. In den Kapitalkosten eines Unternehmens, das eine serverseitige Anwendung anbietet, ist dies der Divisor.
Seit Jahren spielte Effizienz in den meisten Endbenutzeranwendungen keine große Rolle. Entwickler konnten davon ausgehen, dass jeder Benutzer einen immer leistungsstärkeren Prozessor auf seinem Schreibtisch haben würde. Und nach dem Parkinsonschen Gesetz hat sich Software erweitert, um die verfügbaren Ressourcen zu nutzen. Das wird sich mit serverseitigen Anwendungen ändern. In dieser Welt werden Hardware und Software zusammen geliefert. Für Unternehmen, die serverseitige Anwendungen anbieten, wird es einen großen Unterschied für das Endergebnis machen, wie viele Benutzer sie pro Server unterstützen können.
In einigen Anwendungen wird der Prozessor der limitierende Faktor sein, und die Ausführungsgeschwindigkeit wird das Wichtigste sein, was zu optimieren ist. Aber oft wird der Speicher die Grenze sein; die Anzahl der gleichzeitigen Benutzer wird durch die Menge an Speicher bestimmt, die Sie für jeden Benutzerdaten benötigen. Die Sprache kann auch hier helfen. Gute Unterstützung für Threads ermöglicht es allen Benutzern, einen einzigen Heap zu teilen. Es kann auch hilfreich sein, persistente Objekte und/oder Sprach-Level-Unterstützung 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 verschwinden könnte, wie so viele Programmiersprachen es tun. Daher werden die meisten Hacker dazu neigen, zu warten, bis eine Sprache ein paar Jahre existiert, bevor sie überhaupt in Erwägung ziehen, sie zu verwenden.
Erfinder von wunderbaren neuen Dingen sind oft überrascht, dies zu entdecken, aber Sie brauchen Zeit, um eine Botschaft an die Menschen zu bringen. Ein Freund von mir macht selten etwas beim ersten Mal, wenn jemand ihn darum bittet. Er weiß, dass Menschen manchmal Dinge verlangen, die sie sich später nicht mehr wünschen. Um seine Zeit nicht zu verschwenden, wartet er bis zum dritten oder vierten Mal, wenn er gebeten wird, etwas zu tun; bis dahin ist derjenige, der ihn darum bittet, vielleicht ziemlich verärgert, aber zumindest will er wahrscheinlich wirklich das, worum er bittet.
Die meisten Menschen haben gelernt, eine ähnliche Art von Filterung auf neue Dinge anzuwenden, von denen sie hören. Sie fangen nicht einmal an, darauf zu achten, bis sie zehnmal von etwas gehört haben. Sie sind vollkommen berechtigt: Die Mehrheit der heißen neuen Dinge erweisen sich als Zeitverschwendung und verschwinden schließlich. Indem ich es vermied, VRML zu lernen, vermied ich es, es überhaupt lernen zu müssen.
Jeder, der etwas Neues erfindet, muss also damit rechnen, seine Botschaft jahrelang zu wiederholen, bevor die Leute anfangen, sie zu verstehen. Wir schrieben, soweit ich weiß, die erste webserverbasierte Anwendung, und es dauerte Jahre, bis wir den Leuten klar machten, dass sie nicht heruntergeladen werden musste. Es war nicht so, dass sie dumm waren. Sie hatten uns einfach ausgeblendet.
Die gute Nachricht ist, dass einfache Wiederholung das Problem löst. Alles, was Sie tun müssen, ist, Ihre Geschichte immer wieder zu erzählen, und irgendwann werden die Leute anfangen zu hören. Es ist nicht, wenn die Leute bemerken, dass Sie da sind, dass sie aufmerksam werden; es ist, wenn sie bemerken, dass Sie immer noch da sind.
Es ist auch gut, dass es normalerweise eine Weile dauert, bis man an Fahrt gewinnt. Die meisten Technologien entwickeln sich auch nach ihrer ersten Einführung noch weiter - Programmiersprachen ganz besonders. Nichts könnte besser sein, für eine neue Technologie, als ein paar Jahre, in denen sie nur von einer kleinen Anzahl von Early Adoptern genutzt wird. Early Adopters sind anspruchsvoll und fordern viel, und sie decken schnell alle Fehler auf, die in Ihrer Technologie noch vorhanden sind. Wenn Sie nur wenige Benutzer haben, können Sie mit allen in engem Kontakt stehen. Und Early Adopters sind nachsichtig, wenn Sie Ihr System verbessern, auch wenn dies zu einigen Brüchen führt.
Es gibt zwei Möglichkeiten, wie neue Technologien eingeführt werden: die organische Wachstumsmethode und die Big-Bang-Methode. Die organische Wachstumsmethode wird durch das klassische, unterfinanzierte Garagen-Startup veranschaulicht. Ein paar Typen, die in der Obskurität arbeiten, entwickeln eine neue Technologie. Sie bringen sie ohne Marketing auf den Markt und haben zunächst nur wenige (fanatisch engagierte) Benutzer. Sie verbessern die Technologie weiter, und währenddessen wächst ihre Benutzerbasis durch Mundpropaganda. Bevor sie es wissen, sind sie groß.
Der andere Ansatz, die Big-Bang-Methode, wird durch das VC-finanzierte, stark vermarktete Startup veranschaulicht. Sie beeilen sich, ein Produkt zu entwickeln, bringen es mit großer Publizität auf den Markt und haben sofort (hoffentlich) eine große Benutzerbasis.
Im Allgemeinen beneiden die Garagen-Typen die Big-Bang-Typen. Die Big-Bang-Typen sind glatt und selbstbewusst und werden von den VCs respektiert. Sie können sich das Beste von allem leisten, und die PR-Kampagne rund um den Start hat den Nebeneffekt, dass sie zu Berühmtheiten werden. Die organischen Wachstumstypen, die in ihrer Garage sitzen, fühlen sich arm und ungeliebt. Und doch glaube ich, dass sie oft falsch liegen, wenn sie sich selbst bemitleiden. Organisches Wachstum scheint zu einer besseren Technologie und reicheren Gründern zu führen als die Big-Bang-Methode. Wenn man sich die dominierenden Technologien von heute ansieht, stellt man fest, dass die meisten von ihnen organisch gewachsen sind.
Dieses Muster gilt nicht nur für Unternehmen. Man sieht es auch bei geförderter Forschung. Multics und Common Lisp waren Big-Bang-Projekte, und Unix und MacLisp waren organische Wachstumsprojekte.
10 Neugestaltung
"Das beste Schreiben ist das Umschreiben", schrieb E. B. White. Jeder gute Schriftsteller weiß das, und es gilt auch für Software. Der wichtigste Teil des Designs ist die Neugestaltung. Programmiersprachen, insbesondere, werden nicht genug neu gestaltet.
Um gute Software zu schreiben, müssen Sie gleichzeitig zwei gegensätzliche Ideen im Kopf behalten. Sie brauchen den naiven Glauben des jungen Hackers an seine Fähigkeiten und gleichzeitig die Skepsis des Veteranen. Sie müssen in der Lage sein, zu denken wie schwer kann es sein? mit der einen Hälfte Ihres Gehirns, während Sie denken es wird nie funktionieren mit der anderen.
Der Trick ist zu erkennen, dass es hier keinen wirklichen Widerspruch gibt. Sie wollen optimistisch und skeptisch gegenüber zwei verschiedenen Dingen sein. Sie müssen optimistisch sein, was die Möglichkeit angeht, das Problem zu lösen, aber skeptisch gegenüber dem Wert der Lösung, die Sie bisher 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 Bewunderung, aber der Schöpfer ist voller Sorgen. Dieses Muster ist kein Zufall: es sind die Sorgen, die die Arbeit gut gemacht haben.
Wenn Sie Hoffnung und Sorge im Gleichgewicht halten können, werden sie ein Projekt vorantreiben, genauso wie Ihre beiden Beine ein Fahrrad vorantreiben. In der ersten Phase der Zwei-Zyklus-Innovationsmaschine arbeiten Sie fieberhaft an einem Problem, inspiriert von Ihrem Vertrauen, dass Sie in der Lage sein werden, es zu lösen. In der zweiten Phase betrachten Sie, was Sie getan haben, im kalten Licht des Morgens und sehen all seine Fehler 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 gehen?, wodurch der Zyklus fortgesetzt wird.
Es ist schwierig, die beiden Kräfte im Gleichgewicht zu halten. Bei jungen Hackern überwiegt der Optimismus. Sie produzieren etwas, sind überzeugt, dass es großartig ist, und verbessern es nie. Bei alten Hackern überwiegt die Skepsis, und sie wagen es nicht einmal, ehrgeizige Projekte anzugehen.
Alles, was Sie tun können, um den Neugestaltungszyklus am Laufen zu halten, ist gut. Prosa kann immer wieder umgeschrieben werden, bis Sie mit ihr zufrieden sind. Aber Software wird in der Regel nicht genug neu gestaltet. Prosa hat Leser, aber Software hat Benutzer. Wenn ein Autor einen Essay umschreibt, werden Leute, die die alte Version gelesen haben, wahrscheinlich nicht beschweren, dass ihre Gedanken durch eine neu eingeführte Inkompatibilität unterbrochen wurden.
Benutzer sind ein zweischneidiges Schwert. Sie können Ihnen helfen, Ihre Sprache zu verbessern, aber sie können Sie auch davon abhalten, sie zu verbessern. Wählen Sie also Ihre Benutzer sorgfältig aus und wachsen Sie langsam in ihrer Anzahl. Benutzer zu haben ist wie Optimierung: Der kluge Weg ist, sie zu verzögern. Außerdem können Sie im Allgemeinen zu jeder Zeit mehr ändern, als Sie denken. Veränderungen einzuführen ist wie das Abziehen eines Verbandes: Der Schmerz ist fast eine Erinnerung, sobald Sie ihn spüren.
Jeder weiß, dass es keine gute Idee ist, eine Sprache von einem Komitee entwerfen zu lassen. Komitees führen zu schlechtem Design. Aber ich denke, die größte Gefahr von Komitees ist, dass sie die Neugestaltung behindern. Es ist so viel Arbeit, Änderungen einzuführen, dass niemand sich die Mühe machen möchte. Was auch immer ein Komitee beschließt, bleibt in der Regel so, auch wenn die meisten Mitglieder es nicht mögen.
Selbst ein Komitee aus zwei Personen behindert die Neugestaltung. Dies geschieht insbesondere bei den Schnittstellen zwischen Softwareteilen, die von zwei verschiedenen Personen geschrieben wurden. Um die Schnittstelle zu ändern, müssen beide zustimmen, sie gleichzeitig zu ändern. Und so ändern sich Schnittstellen in der Regel überhaupt nicht, was ein Problem ist, weil sie in der Regel zu den am meisten ad-hoc gebauten Teilen eines Systems gehören.
Eine Lösung könnte hier sein, Systeme so zu gestalten, dass Schnittstellen horizontal statt vertikal sind - so dass Module immer vertikal gestapelte Schichten der Abstraktion sind. Dann wird die Schnittstelle in der Regel von einer von ihnen besessen sein. 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 Sklave sein, in diesem Fall kann die Schnittstelle von der oberen Ebene diktiert werden.
11 Lisp
Was all dies impliziert, ist, dass es Hoffnung für ein neues Lisp gibt. Es gibt Hoffnung für jede Sprache, die Hackern das gibt, was sie wollen, einschließlich Lisp. Ich denke, wir haben einen Fehler gemacht, als wir dachten, dass Hacker von Lisps Seltsamkeit abgeschreckt werden. Diese tröstliche Illusion hat uns vielleicht verhindert, das eigentliche Problem mit Lisp zu sehen, oder zumindest mit Common Lisp, nämlich dass es zum Scheitern verurteilt ist, das zu tun, 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 es nicht.
Die gute Nachricht ist, dass nicht Lisp schlecht ist, sondern Common Lisp. Wenn wir ein neues Lisp entwickeln können, das eine echte Hackersprache ist, glaube ich, dass Hacker es verwenden werden. Sie werden jede Sprache verwenden, die die Aufgabe erfüllt. Alles, was wir tun müssen, ist, sicherzustellen, dass dieses neue Lisp einige wichtige Aufgaben 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 Sie erstellt haben, Lisp ist. Die neueste heiße Sprache, Python, ist ein verwässertes Lisp mit Infix-Syntax und ohne Makros. Ein neues Lisp wäre ein natürlicher Schritt in dieser Progression.
Ich denke manchmal, dass es ein guter Marketingtrick wäre, es eine verbesserte Version von Python zu nennen. Das klingt hipper als Lisp. Für viele Menschen ist Lisp eine langsame KI-Sprache mit vielen Klammern. Fritz Kunzes offizielle Biografie vermeidet es sorgfältig, das L-Wort zu erwähnen. Aber ich vermute, dass wir keine Angst haben sollten, das neue Lisp Lisp zu nennen. Lisp genießt immer noch viel latenten Respekt unter den allerbesten Hackern - denen, die 6.001 belegt haben und es verstanden haben, zum Beispiel. Und das sind die Benutzer, die Sie gewinnen müssen.
In "How to Become a Hacker" beschreibt Eric Raymond Lisp als etwas wie Latein oder Griechisch - eine Sprache, die man als intellektuelle Übung lernen sollte, obwohl man sie nicht wirklich verwenden wird:
Lisp ist es wert, gelernt zu werden, wegen der tiefgreifenden Erleuchtungserfahrung, die Sie haben werden, wenn Sie es endlich verstanden haben; diese Erfahrung wird Sie für den Rest Ihrer Tage zu einem besseren Programmierer machen, auch wenn Sie Lisp selbst nie wirklich viel verwenden.
Wenn ich Lisp nicht kennen würde, würde mich das Lesen dieses Textes Fragen stellen lassen. Eine Sprache, die mich zu einem besseren Programmierer machen würde, wenn es überhaupt etwas bedeutet, bedeutet eine Sprache, die besser zum Programmieren geeignet wäre. Und das ist in der Tat die Implikation von dem, was Eric sagt.
Solange diese Idee noch herumschwirrt, glaube ich, dass Hacker einem neuen Lisp gegenüber aufgeschlossen sein werden, auch 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 leistungsstarke Bibliotheken haben, um das zu tun, was Hacker jetzt tun wollen.
In Bezug auf Bibliotheken glaube ich, dass es Raum gibt, Sprachen wie Perl und Python in ihrem eigenen Spiel zu schlagen. Viele der neuen Anwendungen, die in den kommenden Jahren geschrieben werden müssen, werden serverseitige Anwendungen sein. Es gibt keinen Grund, warum ein neues Lisp nicht über String-Bibliotheken verfügen sollte, die so gut sind wie Perl, und wenn dieses neue Lisp auch über leistungsstarke Bibliotheken für serverseitige Anwendungen verfügen würde, könnte es sehr beliebt werden. Echte Hacker werden die Nase nicht über ein neues Werkzeug rümpfen, 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, Kern-Sprach-Unterstützung für serverseitige Anwendungen zu haben. Zum Beispiel explizite Unterstützung für Programme mit mehreren Benutzern oder Datenbesitz auf der Ebene von Typ-Tags.
Serverbasierte Anwendungen geben uns auch die Antwort auf die Frage, wozu diese neue Lisp verwendet 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 vielleicht 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 Wahl für serverbasierte Anwendungen. Lexikalische Schließungen bieten eine Möglichkeit, den Effekt von Subroutinen zu erzielen, wenn die Benutzeroberfläche nur aus einer Reihe von Webseiten besteht. S-Ausdrücke lassen sich gut auf HTML abbilden, und Makros eignen sich gut zum Generieren von HTML. Es müssen bessere Werkzeuge zum Schreiben serverbasierter Anwendungen geben, und es muss eine neue Lisp geben, und die beiden würden sehr gut zusammenarbeiten.
12 Die Traumsprache
Zusammenfassend wollen wir versuchen, die Traumsprache des Hackers zu beschreiben. Die Traumsprache ist schön, sauber und knapp. Sie hat eine interaktive Topebene, 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 bis zur Unkenntlichkeit kurz. Sie müssen nie ein unnötiges Zeichen eingeben oder die Umschalttaste überhaupt oft benutzen.
Mit großen Abstraktionen können Sie die erste Version eines Programms sehr schnell schreiben. Später, wenn Sie optimieren wollen, gibt es einen wirklich guten Profiler, der Ihnen sagt, wo Sie Ihre Aufmerksamkeit konzentrieren sollen. Sie können innere Schleifen blendend schnell machen, sogar Inline-Bytecode schreiben, wenn Sie müssen.
Es gibt viele gute Beispiele, aus denen man lernen kann, und die Sprache ist intuitiv genug, dass man lernen kann, sie zu benutzen, indem man sich ein paar Minuten lang Beispiele anschaut. Sie müssen nicht viel 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 so sorgfältig entworfen sind wie die Kernsprache. Die Bibliotheken funktionieren alle gut zusammen; alles in der Sprache passt zusammen wie die Teile einer guten Kamera. Nichts ist veraltet oder aus Kompatibilitätsgründen beibehalten. Der Quellcode aller Bibliotheken ist leicht verfügbar. Es ist einfach, mit dem Betriebssystem und mit Anwendungen zu kommunizieren, die in anderen Sprachen geschrieben sind.
Die Sprache ist in Schichten aufgebaut. Die höherwertigen Abstraktionen sind auf eine sehr transparente Weise aus niedrigeren Abstraktionen aufgebaut, die Sie sich holen können, wenn Sie wollen.
Nichts wird vor Ihnen verborgen, was nicht unbedingt sein muss. Die Sprache bietet Abstraktionen nur als eine Möglichkeit, Ihnen Arbeit zu ersparen, anstatt Ihnen zu sagen, was Sie tun sollen. Tatsächlich ermutigt Sie die Sprache, ein gleichberechtigter Teilnehmer an ihrer Gestaltung zu sein. Sie können alles daran ändern, einschließlich der Syntax, und alles, was Sie schreiben, hat, so weit wie möglich, den gleichen Status wie das, was vordefiniert ist.
Hinweise
[1] Makros, die dem modernen Konzept sehr nahe kommen, wurden 1964 von Timothy Hart vorgeschlagen, zwei Jahre nachdem Lisp 1.5 veröffentlicht wurde. Was zunächst fehlte, waren Möglichkeiten, Variablenfang und mehrfache Auswertung zu vermeiden; Harts Beispiele sind beidem unterworfen.
[2] In When the Air Hits Your Brain, erzählt der Neurochirurg Frank Vertosick von einem 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 eine freie Kabine. Der Chef zündete sich eine Zigarette an. "Schau dir diese verdammten Flöhe an, die da über irgendeine Krankheit plappern, die sie einmal in ihrem Leben sehen werden. 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 Lendenwirbel-Bandscheibenvorfälle, aber sie hassen Hypertonie...."
Es ist schwer, sich einen Lendenwirbel-Bandscheibenvorfall als saftig vorzustellen (außer im wörtlichen Sinne). Und doch glaube ich, dass ich weiß, was sie meinen. Ich hatte oft einen saftigen Fehler zu jagen. Jemand, der kein Programmierer ist, würde es schwer finden, sich vorzustellen, dass es Vergnügen an einem Fehler geben könnte. Sicherlich ist es besser, wenn alles einfach funktioniert. In gewisser Weise ist es das auch. Und doch gibt es unbestreitbar eine düstere Befriedigung, bestimmte Arten von Fehlern zu jagen.