Loading...

FÜNF FRAGEN ZUM SPRACHDESIGN

Original

Mai 2001

(Dies sind einige Notizen, die ich für eine Podiumsdiskussion über das Design von Programmiersprachen am MIT am 10. Mai 2001 gemacht habe.)

1. Programmiersprachen sind für Menschen.

Programmiersprachen sind, wie Menschen mit Computern kommunizieren. Der Computer wäre genauso glücklich, jede Sprache zu sprechen, die eindeutig ist. Der Grund, warum wir Hochsprachen haben, ist, dass Menschen mit Maschinensprache nicht umgehen können. Der Sinn von Programmiersprachen ist es, zu verhindern, dass unsere armen, schwachen menschlichen Gehirne von einer Masse an Details überwältigt werden.

Architekten wissen, dass einige Arten von Designproblemen persönlicher sind als andere. Eines der klarsten, abstraktesten Designprobleme ist das Entwerfen von Brücken. Dort besteht Ihre Aufgabe größtenteils darin, eine gegebene Distanz mit dem geringsten Material zu überspannen. Am anderen Ende des Spektrums steht das Entwerfen von Stühlen. Stuhldesigner müssen ihre Zeit damit verbringen, über menschliche Hinterteile nachzudenken.

Software variiert auf die gleiche Weise. Algorithmen für die Datenweiterleitung durch ein Netzwerk zu entwerfen, ist ein schönes, abstraktes Problem, wie das Entwerfen von Brücken. Während das Entwerfen von Programmiersprachen wie das Entwerfen von Stühlen ist: Es geht darum, mit menschlichen Schwächen umzugehen.

Die meisten von uns hassen es, dies anzuerkennen. Systeme von großer mathematischer Eleganz zu entwerfen, klingt für die meisten von uns viel ansprechender, als sich mit menschlichen Schwächen auseinanderzusetzen. Und es gibt eine Rolle für mathematische Eleganz: Einige Arten von Eleganz machen Programme leichter verständlich. Aber Eleganz ist kein Selbstzweck.

Und wenn ich sage, dass Sprachen so gestaltet werden müssen, dass sie menschlichen Schwächen gerecht werden, meine ich nicht, dass Sprachen für schlechte Programmierer entworfen werden müssen. Tatsächlich denke ich, dass Sie für die besten Programmierer entwerfen sollten, aber selbst die besten Programmierer haben Einschränkungen. Ich glaube nicht, dass es jemandem gefallen würde, in einer Sprache zu programmieren, in der alle Variablen der Buchstabe x mit ganzzahligen Indizes waren.

2. Entwerfen Sie für sich selbst und Ihre Freunde.

Wenn Sie sich die Geschichte der Programmiersprachen ansehen, wurden viele der besten Sprachen für ihre eigenen Autoren entworfen, und viele der schlechtesten wurden für andere Menschen entworfen.

Wenn Sprachen für andere Menschen entworfen werden, handelt es sich immer um eine spezifische Gruppe anderer Menschen: Menschen, die nicht so klug sind wie der Sprachdesigner. So erhalten Sie eine Sprache, die herablassend zu Ihnen spricht. Cobol ist der extremste Fall, aber viele Sprachen sind von diesem Geist durchdrungen.

Es hat nichts damit zu tun, wie abstrakt die Sprache ist. C ist ziemlich niedrigstufig, aber es wurde für seine Autoren entworfen, und das ist der Grund, warum Hacker es mögen.

Das Argument für das Entwerfen von Sprachen für schlechte Programmierer ist, dass es mehr schlechte Programmierer als gute Programmierer gibt. Das mag so sein. Aber diese wenigen guten Programmierer schreiben einen unverhältnismäßig großen Prozentsatz der Software.

Ich interessiere mich für die Frage, wie man eine Sprache entwirft, die die besten Hacker mögen werden? Ich denke, das ist identisch mit der Frage, wie man eine gute Programmiersprache entwirft?, aber selbst wenn es das nicht ist, ist es zumindest eine interessante Frage.

3. Geben Sie dem Programmierer so viel Kontrolle wie möglich.

Viele Sprachen (insbesondere die, die für andere Menschen entworfen wurden) haben die Einstellung einer Gouvernante: Sie versuchen, Sie davon abzuhalten, Dinge zu tun, von denen sie denken, dass sie nicht gut für Sie sind. Ich mag den gegenteiligen Ansatz: Geben Sie dem Programmierer so viel Kontrolle, wie Sie können.

Als ich zum ersten Mal Lisp lernte, gefiel mir am meisten, dass es mich als gleichwertigen Partner betrachtete. In den anderen Sprachen, die ich bis dahin gelernt hatte, gab es die Sprache und es gab mein Programm, das in der Sprache geschrieben war, und die beiden waren sehr getrennt. Aber in Lisp waren die Funktionen und Makros, die ich schrieb, genau wie die, die die Sprache selbst ausmachten. Ich konnte die Sprache umschreiben, wenn ich wollte. Es hatte den gleichen Reiz wie Open-Source-Software.

4. Streben Sie nach Kürze.

Kürze wird unterschätzt und sogar verachtet. Aber wenn Sie in die Herzen der Hacker schauen, werden Sie sehen, dass sie es wirklich lieben. Wie oft haben Sie Hacker liebevoll darüber sprechen hören, wie sie in APL erstaunliche Dinge mit nur ein paar Zeilen Code tun konnten? Ich denke, alles, was wirklich klugen Menschen wirklich gefällt, ist es wert, beachtet zu werden.

Ich denke, fast alles, was Sie tun können, um Programme kürzer zu machen, ist gut. Es sollte viele Bibliotheksfunktionen geben; alles, was implizit sein kann, sollte es sein; die Syntax sollte auf den Punkt gebracht sein; selbst die Namen von Dingen sollten kurz sein.

Und es sind nicht nur Programme, die kurz sein sollten. Das Handbuch sollte ebenfalls dünn sein. Ein guter Teil der Handbücher ist mit Klarstellungen, Vorbehalten, Warnungen und Sonderfällen gefüllt. Wenn Sie sich zwingen, das Handbuch zu verkürzen, tun Sie dies im besten Fall, indem Sie die Dinge in der Sprache beheben, die so viel Erklärung erforderten.

5. Geben Sie zu, was Hacking ist.

Viele Menschen wünschen sich, dass Hacking Mathematik oder zumindest etwas wie eine Naturwissenschaft ist. Ich denke, Hacking ist mehr wie Architektur. Architektur steht in Beziehung zur Physik, insofern Architekten Gebäude entwerfen müssen, die nicht einstürzen, aber das eigentliche Ziel von Architekten ist es, großartige Gebäude zu schaffen, nicht Entdeckungen über Statik zu machen.

Was Hacker gerne tun, ist, großartige Programme zu erstellen. Und ich denke, zumindest in unseren eigenen Köpfen, müssen wir uns daran erinnern, dass es bewundernswert ist, großartige Programme zu schreiben, selbst wenn diese Arbeit sich nicht leicht in die konventionelle intellektuelle Währung von Forschungsarbeiten übersetzen lässt. Intellektuell ist es ebenso wertvoll, eine Sprache zu entwerfen, die Programmierer lieben werden, wie eine schreckliche zu entwerfen, die eine Idee verkörpert, über die Sie ein Papier veröffentlichen können.

1. Wie organisiert man große Bibliotheken?

Bibliotheken werden zu einem zunehmend wichtigen Bestandteil von Programmiersprachen. Sie werden auch größer, und das kann gefährlich sein. Wenn es länger dauert, die Bibliotheksfunktion zu finden, die das tut, was Sie wollen, als es dauern würde, sie selbst zu schreiben, dann macht all dieser Code nichts anderes, als Ihr Handbuch dick zu machen. (Die Symbolics-Handbücher waren ein Beispiel dafür.) Daher denke ich, dass wir an Möglichkeiten arbeiten müssen, Bibliotheken zu organisieren. Ideal wäre es, sie so zu gestalten, dass der Programmierer erraten kann, welcher Bibliotheksaufruf das Richtige tun würde.

2. Haben Menschen wirklich Angst vor Präfix-Syntax?

Das ist ein offenes Problem, insofern ich mich seit Jahren darüber wundere und immer noch nicht die Antwort kenne. Präfix-Syntax erscheint mir vollkommen natürlich, außer vielleicht in der Mathematik. Aber es könnte sein, dass ein großer Teil der Unbeliebtheit von Lisp einfach auf die ungewohnte Syntax zurückzuführen ist. Ob man etwas dagegen tun sollte, wenn das wahr ist, ist eine andere Frage.

3. Was braucht man für serverbasierte Software?

Ich denke, viele der aufregendsten neuen Anwendungen, die in den nächsten zwanzig Jahren geschrieben werden, werden webbasierte Anwendungen sein, also Programme, die auf dem Server sitzen und über einen Webbrowser mit Ihnen kommunizieren. Und um diese Art von Programmen zu schreiben, benötigen wir möglicherweise einige neue Dinge.

Eine Sache, die wir brauchen werden, ist Unterstützung für die neue Art, wie serverbasierte Apps veröffentlicht werden. Anstatt ein oder zwei große Veröffentlichungen pro Jahr zu haben, wie bei Desktop-Software, werden serverbasierte Apps als eine Reihe kleiner Änderungen veröffentlicht. Sie können bis zu fünf oder zehn Veröffentlichungen pro Tag haben. Und in der Regel wird jeder immer die neueste Version verwenden.

Sie wissen, wie Sie Programme so entwerfen können, dass sie debugbar sind? Nun, serverbasierte Software muss ebenfalls so entworfen werden, dass sie änderbar ist. Sie müssen in der Lage sein, sie einfach zu ändern oder zumindest zu wissen, was eine kleine Änderung und was eine bedeutende ist.

Eine weitere Sache, die sich als nützlich für serverbasierte Software herausstellen könnte, sind überraschenderweise Fortsetzungen. In webbasierter Software können Sie etwas wie den Fortsetzungsübergangsstil verwenden, um den Effekt von Unterprogrammen in der von Natur aus zustandslosen Welt einer Websitzung zu erzielen. Vielleicht wäre es lohnenswert, tatsächliche Fortsetzungen zu haben, wenn es nicht zu teuer wäre.

4. Welche neuen Abstraktionen sind noch zu entdecken?

Ich bin mir nicht sicher, wie vernünftig diese Hoffnung ist, aber eine Sache, die ich persönlich wirklich gerne tun würde, ist, eine neue Abstraktion zu entdecken – etwas, das einen ebenso großen Unterschied machen würde wie erstklassige Funktionen oder Rekursion oder sogar Schlüsselwortparameter. Das könnte ein unerreichbarer Traum sein. Diese Dinge werden nicht so oft entdeckt. Aber ich suche immer.

1. Sie können jede Sprache verwenden, die Sie möchten.

Anwendungsprogramme zu schreiben bedeutete früher, Desktop-Software zu schreiben. Und in der Desktop-Software gibt es eine große Neigung, die Anwendung in derselben Sprache wie das Betriebssystem zu schreiben. Und so bedeutete das Schreiben von Software vor zehn Jahren ziemlich genau, Software in C zu schreiben. Schließlich entwickelte sich eine Tradition: Anwendungsprogramme dürfen nicht in ungewöhnlichen Sprachen geschrieben werden. Und diese Tradition hatte so lange Zeit, sich zu entwickeln, dass auch nicht-technische Menschen wie Manager und Risikokapitalgeber sie lernten.

Serverbasierte Software sprengt dieses gesamte Modell. Mit serverbasierter Software können Sie jede Sprache verwenden, die Sie möchten. Fast niemand versteht das bisher (insbesondere nicht Manager und Risikokapitalgeber). Einige Hacker verstehen es, und deshalb hören wir überhaupt von neuen, unabhängigen Sprachen wie Perl und Python. Wir hören nicht von Perl und Python, weil Menschen sie verwenden, um Windows-Apps zu schreiben.

Was das für uns bedeutet, als Menschen, die sich für das Design von Programmiersprachen interessieren, ist, dass es jetzt potenziell ein tatsächliches Publikum für unsere Arbeit gibt.

2. Geschwindigkeit kommt von Profilern.

Sprachdesigner oder zumindest Sprachimplementierer schreiben gerne Compiler, die schnellen Code generieren. Aber ich denke nicht, dass das das ist, was Sprachen für Benutzer schnell macht. Knuth wies schon vor langer Zeit darauf hin, dass Geschwindigkeit nur in wenigen kritischen Engpässen wichtig ist. Und jeder, der es versucht hat, weiß, dass man nicht erraten kann, wo diese Engpässe sind. Profiler sind die Antwort.

Sprachdesigner lösen das falsche Problem. Benutzer benötigen keine Benchmarks, um schnell zu laufen. Was sie brauchen, ist eine Sprache, die ihnen zeigt, welche Teile ihrer eigenen Programme neu geschrieben werden müssen. Dort kommt die Geschwindigkeit in der Praxis her. Vielleicht wäre es also ein Gewinn, wenn Sprachimplementierer die Hälfte der Zeit, die sie mit Compileroptimierungen verbringen würden, stattdessen damit verbringen, einen guten Profiler zu schreiben.

3. Sie benötigen eine Anwendung, um das Design einer Sprache voranzutreiben.

Das mag keine absolute Regel sein, aber es scheint, dass die besten Sprachen alle zusammen mit einer Anwendung entstanden sind, für die sie verwendet wurden. C wurde von Menschen geschrieben, die es für die Systemprogrammierung benötigten. Lisp wurde teilweise entwickelt, um symbolische Differenzierung durchzuführen, und McCarthy war so eifrig, loszulegen, dass er sogar im ersten Papier über Lisp im Jahr 1960 Differenzierungsprogramme schrieb.

Es ist besonders gut, wenn Ihre Anwendung ein neues Problem löst. Das wird dazu tendieren, Ihre Sprache dazu zu bringen, neue Funktionen zu haben, die Programmierer benötigen. Ich persönlich interessiere mich dafür, eine Sprache zu schreiben, die gut für das Schreiben serverbasierter Anwendungen geeignet ist.

[Während des Panels machte Guy Steele auch diesen Punkt, mit dem zusätzlichen Vorschlag, dass die Anwendung nicht darin bestehen sollte, den Compiler für Ihre Sprache zu schreiben, es sei denn, Ihre Sprache ist zufällig für das Schreiben von Compilern gedacht.]

4. Eine Sprache muss gut für das Schreiben von Wegwerfprogrammen sein.

Sie wissen, was ein Wegwerfprogramm ist: etwas, das Sie schnell für eine begrenzte Aufgabe schreiben. Ich denke, wenn Sie sich umsehen würden, würden Sie feststellen, dass viele große, ernsthafte Programme als Wegwerfprogramme begonnen haben. Ich wäre nicht überrascht, wenn die meisten Programme als Wegwerfprogramme begonnen haben. Und wenn Sie also eine Sprache erstellen möchten, die gut für das Schreiben von Software im Allgemeinen ist, muss sie gut für das Schreiben von Wegwerfprogrammen sein, denn das ist die larvale Phase der meisten Software.

5. Syntax ist mit Semantik verbunden.

Es ist traditionell zu denken, dass Syntax und Semantik völlig getrennt sind. Das wird schockierend klingen, aber es könnte sein, dass sie es nicht sind. Ich denke, dass das, was Sie in Ihrer Sprache wollen, möglicherweise damit zusammenhängt, wie Sie es ausdrücken.

Ich habe kürzlich mit Robert Morris gesprochen, und er wies darauf hin, dass Operatorüberladung in Sprachen mit Infix-Syntax einen größeren Gewinn darstellt. In einer Sprache mit Präfix-Syntax ist jede Funktion, die Sie definieren, effektiv ein Operator. Wenn Sie einen Plusoperator für einen neuen Typ von Zahlen definieren möchten, den Sie erfunden haben, können Sie einfach eine neue Funktion definieren, um sie zu addieren. Wenn Sie das in einer Sprache mit Infix-Syntax tun, gibt es einen großen Unterschied im Aussehen zwischen der Verwendung eines überladenen Operators und einem Funktionsaufruf.

1. Neue Programmiersprachen.

In den 1970er Jahren war es in Mode, neue Programmiersprachen zu entwerfen. In letzter Zeit war es das nicht. Aber ich denke, serverbasierte Software wird neue Sprachen wieder in Mode bringen. Mit serverbasierter Software können Sie jede Sprache verwenden, die Sie möchten, also wenn jemand eine Sprache entwirft, die tatsächlich besser zu sein scheint als andere, die verfügbar sind, wird es Menschen geben, die ein Risiko eingehen und sie verwenden.

2. Zeitteilung.

Richard Kelsey nannte dies als eine Idee, deren Zeit im letzten Panel wieder gekommen ist, und ich stimme ihm vollkommen zu. Mein Eindruck (und der Eindruck von Microsoft, scheint es) ist, dass viel Rechnen vom Desktop auf entfernte Server verlagert wird. Mit anderen Worten, Zeitteilung ist zurück. Und ich denke, es wird Unterstützung auf Sprachebene dafür benötigt werden. Zum Beispiel weiß ich, dass Richard und Jonathan Rees viel Arbeit in die Implementierung der Prozessplanung innerhalb von Scheme 48 gesteckt haben.

3. Effizienz.

Kürzlich begann es so auszusehen, als wären Computer endlich schnell genug. Immer mehr hörten wir von Bytecode, was für mich zumindest impliziert, dass wir das Gefühl haben, wir hätten Zyklen übrig. Aber ich denke nicht, dass wir das mit serverbasierter Software haben werden. Jemand wird für die Server bezahlen müssen, auf denen die Software läuft, und die Anzahl der Benutzer, die sie pro Maschine unterstützen können, wird der Divisor ihrer Kapitalkosten sein.

Daher denke ich, dass Effizienz wichtig sein wird, zumindest in rechnerischen Engpässen. Es wird besonders wichtig sein, I/O schnell zu machen, da serverbasierte Anwendungen viel I/O durchführen.

Es könnte sich herausstellen, dass Bytecode am Ende kein Gewinn ist. Sun und Microsoft scheinen sich im Moment in einer Art Wettkampf der Bytecodes gegenüberzustehen. Aber sie tun es, weil Bytecode ein bequemer Ort ist, um sich in den Prozess einzufügen, nicht weil Bytecode an sich eine gute Idee ist. Es könnte sich herausstellen, dass dieses gesamte Schlachtfeld umgangen wird. Das wäre irgendwie amüsant.

1. Clients.

Das ist nur eine Vermutung, aber meine Vermutung ist, dass das gewinnende Modell für die meisten Anwendungen rein serverbasiert sein wird. Software zu entwerfen, die davon ausgeht, dass jeder Ihren Client haben wird, ist wie eine Gesellschaft zu entwerfen, die davon ausgeht, dass jeder einfach ehrlich sein wird. Es wäre sicherlich praktisch, aber Sie müssen davon ausgehen, dass es niemals passieren wird.

Ich denke, es wird eine Vielzahl von Geräten geben, die irgendeine Art von Webzugang haben, und alles, was Sie über sie annehmen können, ist, dass sie einfaches HTML und Formulare unterstützen können. Werden Sie einen Browser auf Ihrem Handy haben? Wird es ein Telefon in Ihrem Palm Pilot geben? Wird Ihr Blackberry einen größeren Bildschirm bekommen? Werden Sie in der Lage sein, das Web auf Ihrem Gameboy zu durchsuchen? Ihre Uhr? Ich weiß es nicht. Und ich muss es nicht wissen, wenn ich darauf setze, dass alles nur auf dem Server ist. Es ist einfach so viel robuster, alle Intelligenz auf dem Server zu haben.

2. Objektorientierte Programmierung.

Ich erkenne, dass dies umstritten ist, aber ich denke nicht, dass objektorientierte Programmierung so wichtig ist. Ich denke, es ist ein gutes Modell für bestimmte Arten von Anwendungen, die diese spezifische Art von Datenstruktur benötigen, wie Fenstersysteme, Simulationen und CAD-Programme. Aber ich sehe nicht, warum es das Modell für alle Programmierung sein sollte.

Ich denke, ein Teil des Grundes, warum Menschen in großen Unternehmen objektorientierte Programmierung mögen, ist, dass sie viel von dem liefert, was wie Arbeit aussieht. Etwas, das natürlich als Liste von Ganzzahlen dargestellt werden könnte, kann jetzt als Klasse mit allerlei Gerüst und Hektik dargestellt werden.

Ein weiterer Reiz der objektorientierten Programmierung ist, dass Methoden Ihnen einen Teil des Effekts von erstklassigen Funktionen geben. Aber das ist alte Nachrichten für Lisp-Programmierer. Wenn Sie tatsächlich erstklassige Funktionen haben, können Sie sie einfach auf die Weise verwenden, die für die jeweilige Aufgabe angemessen ist, anstatt alles in eine Form von Klassen und Methoden zu zwängen.

Was das für das Sprachdesign bedeutet, denke ich, ist, dass Sie objektorientierte Programmierung nicht zu tief einbauen sollten. Vielleicht ist die Antwort, allgemeinere, zugrunde liegende Dinge anzubieten und den Menschen zu erlauben, welche Objektsysteme sie wollen, als Bibliotheken zu entwerfen.

3. Design durch Komitee.

Eine Sprache von einem Komitee entwerfen zu lassen, ist eine große Falle, und nicht nur aus den Gründen, die jeder kennt. Jeder weiß, dass Komitees dazu neigen, klumpige, inkonsistente Designs zu liefern. Aber ich denke, eine größere Gefahr besteht darin, dass sie keine Risiken eingehen. Wenn eine Person die Kontrolle hat, kann sie Risiken eingehen, die ein Komitee niemals zustimmen würde.

Ist es jedoch notwendig, Risiken einzugehen, um eine gute Sprache zu entwerfen? Viele Menschen könnten vermuten, dass das Design von Sprachen etwas ist, bei dem man sich ziemlich nah an die konventionelle Weisheit halten sollte. Ich wette, das ist nicht wahr. In allem, was Menschen tun, ist die Belohnung proportional zum Risiko. Warum sollte das Design von Sprachen anders sein?