Loading...

FÜNF FRAGEN ZUM SPRACHDESIGN

Original

Mai 2001

(Dies sind einige Notizen, die ich für eine Podiumsdiskussion zum Thema Programmiersprachendesign am MIT am 10. Mai 2001 gemacht habe.)

1. Programmiersprachen sind für Menschen.

Programmiersprachen sind die Art und Weise, wie Menschen mit Computern kommunizieren. Der Computer würde jede Sprache, die eindeutig ist, genauso gerne sprechen. Der Grund, warum wir Hochsprachen haben, ist, dass Menschen mit Maschinensprachen nicht umgehen können. Der Sinn von Programmiersprachen besteht darin, zu verhindern, dass unser armes, schwaches menschliches Gehirn von einer Masse an Details überwältigt wird.

Architekten wissen, dass manche Designprobleme persönlicher sind als andere. Eines der saubersten und abstraktesten Designprobleme ist das Entwerfen von Brücken. Dabei geht es im Wesentlichen darum, eine bestimmte Distanz mit möglichst wenig Material zu überbrücken. Am anderen Ende des Spektrums steht das Entwerfen von Stühlen. Stuhldesigner müssen ihre Zeit damit verbringen, über menschliche Hinterteile nachzudenken.

Auch Software ist unterschiedlich. Das Entwerfen von Algorithmen zum Leiten von Daten durch ein Netzwerk ist ein schönes, abstraktes Problem, ähnlich dem Entwerfen von Brücken. Das Entwerfen von Programmiersprachen hingegen ist wie das Entwerfen von Stühlen: Es geht darum, mit menschlichen Schwächen umzugehen.

Die meisten von uns geben das nur ungern zu. Systeme mit großer mathematischer Eleganz zu entwerfen, klingt für die meisten von uns viel verlockender, als menschliche Schwächen auszunutzen. Und mathematische Eleganz hat ihren Zweck: Manche 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 damit nicht, dass Sprachen für schlechte Programmierer gestaltet werden müssen. Tatsächlich bin ich der Meinung, dass man Sprachen für die besten Programmierer gestalten sollte, aber selbst die besten Programmierer haben ihre Grenzen. Ich glaube nicht, dass irgendjemand gerne in einer Sprache programmieren würde, in der alle Variablen der Buchstabe x mit ganzzahligen Indizes wären.

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

Wenn Sie sich die Geschichte der Programmiersprachen ansehen, werden Sie feststellen, dass viele der besten Sprachen für die Verwendung durch ihre eigenen Autoren entwickelt wurden, während viele der schlechtesten Sprachen für die Verwendung durch andere entwickelt wurden.

Wenn Sprachen für andere Leute entwickelt werden, geht es immer um eine bestimmte Gruppe anderer Leute: Leute, die nicht so schlau sind wie der Sprachentwickler. So entsteht eine Sprache, die von oben herab mit 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 Low-Level, wurde aber für die Verwendung durch seine Autoren entwickelt und deshalb mögen Hacker es.

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

Mich interessiert die Frage: „Wie entwirft man eine Sprache, die den allerbesten Hackern gefällt?“ Ich bin der Meinung, dass diese Frage identisch ist mit der Frage: „Wie entwirft man eine gute Programmiersprache?“, aber selbst wenn das nicht der Fall 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 Leute entwickelt wurden) haben die Haltung einer Gouvernante: Sie versuchen, Sie davon abzuhalten, Dinge zu tun, von denen sie denken, dass sie nicht gut für Sie sind. Ich bevorzuge den umgekehrten Ansatz: Geben Sie dem Programmierer so viel Kontrolle wie möglich.

Als ich Lisp zum ersten Mal lernte, gefiel mir am besten, dass ich als gleichberechtigter Partner angesehen wurde. In den anderen Sprachen, die ich bis dahin gelernt hatte, gab es die Sprache und mein Programm, das in der Sprache geschrieben war, und die beiden waren völlig getrennt. Aber in Lisp waren die Funktionen und Makros, die ich schrieb, genau wie diejenigen, aus denen die Sprache selbst bestand. Ich konnte die Sprache umschreiben, wenn ich wollte. Es hatte denselben 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 sie wirklich lieben. Wie oft haben Sie Hacker schon liebevoll darüber sprechen hören, wie sie beispielsweise in APL mit nur ein paar Zeilen Code erstaunliche Dinge tun könnten? Ich denke, alles, was wirklich kluge Leute wirklich lieben, ist es wert, beachtet zu werden.

Ich denke, dass fast alles, was man tun kann, um Programme kürzer zu machen, gut ist. Es sollten viele Bibliotheksfunktionen vorhanden sein; alles, was implizit sein kann, sollte es auch sein; die Syntax sollte extrem knapp sein; sogar die Namen der Dinge sollten kurz sein.

Und nicht nur Programme sollten kurz sein. Auch das Handbuch sollte dünn sein. Ein Großteil des Handbuchs besteht aus Klarstellungen, Vorbehalten, Warnungen und Sonderfällen. Wenn Sie sich zwingen, das Handbuch zu kürzen, tun Sie dies im besten Fall, indem Sie die Dinge in der Sprache korrigieren, die so viele Erklärungen erforderten.

5. Geben Sie zu, was Hacking ist.

Viele Leute wünschen sich, Hacken wäre Mathematik oder zumindest so etwas wie eine Naturwissenschaft. Ich glaube, Hacken ist eher wie Architektur. Architektur ist insofern mit Physik verwandt, als dass Architekten Gebäude entwerfen müssen, die nicht einstürzen, aber das eigentliche Ziel von Architekten ist es, großartige Gebäude zu bauen, und nicht, Entdeckungen über Statik zu machen.

Hacker machen gern großartige Programme. Und ich denke, zumindest in unseren eigenen Gedanken sollten wir uns daran erinnern, dass es eine bewundernswerte Sache ist, großartige Programme zu schreiben, selbst wenn sich diese Arbeit nicht so leicht in die herkömmliche intellektuelle Währung von Forschungsarbeiten übertragen lässt. Intellektuell ist es genauso lohnenswert, eine Sprache zu entwickeln, die Programmierer lieben werden, wie eine schreckliche Sprache zu entwickeln, die eine Idee verkörpert, über die man eine Arbeit veröffentlichen kann.

1. Wie organisiert man große Bibliotheken?

Bibliotheken werden zu einem immer wichtigeren Bestandteil von Programmiersprachen. Sie werden aber auch immer größer, und das kann gefährlich sein. Wenn es länger dauert, die Bibliotheksfunktion zu finden, die das gewünschte Ergebnis liefert, als wenn man sie selbst schreiben würde, dann macht der ganze Code Ihr Handbuch nur dicker. (Die Symbolics-Handbücher waren ein typisches Beispiel.) Ich denke also, wir müssen an Möglichkeiten arbeiten, Bibliotheken zu organisieren. Ideal wäre es, sie so zu gestalten, dass der Programmierer erraten kann, welcher Bibliotheksaufruf das Richtige bewirken würde.

2. Haben die Leute wirklich Angst vor der Präfixsyntax?

Dies ist ein offenes Problem in dem Sinne, dass ich mich jahrelang damit beschäftigt habe und immer noch keine Antwort darauf weiß. Die Präfixsyntax erscheint mir völlig natürlich, außer vielleicht in der Mathematik. Aber es könnte sein, dass ein Großteil der Unbeliebtheit von Lisp einfach auf eine ungewohnte Syntax zurückzuführen ist. Ob man etwas dagegen unternehmen sollte, wenn es stimmt, ist eine andere Frage.

3. Was benötigen Sie für serverbasierte Software?

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

Was wir brauchen, ist die Unterstützung der neuen Art und Weise, wie serverbasierte Apps veröffentlicht werden. Anstatt ein oder zwei große Releases pro Jahr zu veröffentlichen, wie es bei Desktop-Software der Fall ist, werden serverbasierte Apps in einer Reihe kleiner Änderungen veröffentlicht. Es können bis zu fünf oder zehn Releases pro Tag erscheinen. Und in der Regel wird jeder immer die neueste Version verwenden.

Wissen Sie, wie Sie Programme so gestalten können, dass sie debuggbar sind? Nun, serverbasierte Software muss ebenso so gestaltet sein, dass sie veränderbar ist. Sie müssen in der Lage sein, sie leicht zu ändern oder zumindest zu wissen, was eine kleine und was eine bedeutsame Änderung ist.

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

4. Welche neuen Abstraktionen gibt es noch zu entdecken?

Ich bin mir nicht sicher, wie vernünftig diese Hoffnung ist, aber was 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 ist vielleicht ein unmöglicher Traum. Diese Dinge werden nicht so oft entdeckt. Aber ich bin immer auf der Suche.

1. Sie können jede gewünschte Sprache verwenden.

Früher bedeutete das Schreiben von Anwendungsprogrammen, Desktop-Software zu schreiben. Und bei Desktop-Software tendiert man stark dazu, die Anwendung in derselben Sprache wie das Betriebssystem zu schreiben. Und so bedeutete das Schreiben von Software vor zehn Jahren im Wesentlichen, Software in C zu schreiben. Irgendwann entwickelte sich eine Tradition: Anwendungsprogramme dürfen nicht in ungewöhnlichen Sprachen geschrieben werden. Und diese Tradition brauchte so lange, um sich zu entwickeln, dass auch Laien wie Manager und Risikokapitalgeber sie lernten.

Serverbasierte Software sprengt dieses ganze Modell. Mit serverbasierter Software können Sie jede beliebige Sprache verwenden. Das versteht bisher fast niemand (vor allem nicht Manager und Risikokapitalgeber). Ein paar Hacker verstehen es, und deshalb hören wir sogar von neuen, unabhängigen Sprachen wie Perl und Python. Wir hören nichts von Perl und Python, weil Leute sie zum Schreiben von Windows-Apps verwenden.

Für uns als Menschen, die sich für die Entwicklung von Programmiersprachen interessieren, bedeutet dies, dass es nun möglicherweise ein echtes Publikum für unsere Arbeit gibt.

2. Geschwindigkeit kommt von Profilern.

Sprachdesigner oder zumindest Sprachimplementierer schreiben gerne Compiler, die schnellen Code generieren. Aber ich glaube nicht, dass dies Sprachen für Benutzer schnell macht. Knuth hat schon vor langer Zeit darauf hingewiesen, dass Geschwindigkeit nur bei einigen kritischen Engpässen eine Rolle spielt. Und jeder, der es ausprobiert hat, weiß, dass man nicht erraten kann, wo diese Engpässe liegen. Profiler sind die Antwort.

Sprachdesigner lösen das falsche Problem. Benutzer brauchen keine Benchmarks, um schnell zu arbeiten. Was sie brauchen, ist eine Sprache, die ihnen zeigt, welche Teile ihrer eigenen Programme neu geschrieben werden müssen. Daraus ergibt sich in der Praxis die Geschwindigkeit. Vielleicht wäre es also ein Nettogewinn, wenn die Sprachimplementierer die Hälfte der Zeit, die sie für Compileroptimierungen aufwenden würden, stattdessen für das Schreiben eines guten Profilers verwenden würden.

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

Dies ist zwar keine absolute Regel, aber es scheint, als hätten sich die besten Sprachen alle zusammen mit einer Anwendung entwickelt, für die sie verwendet wurden. C wurde von Leuten geschrieben, die es für die Systemprogrammierung brauchten. Lisp wurde teilweise entwickelt, um symbolische Differenzierung durchzuführen, und McCarthy war so erpicht darauf, loszulegen, dass er bereits in seinem ersten Artikel über Lisp im Jahr 1960 Differenzierungsprogramme schrieb.

Es ist besonders gut, wenn Ihre Anwendung ein neues Problem löst. Das wird dazu führen, dass Ihre Sprache neue Funktionen erhält, die Programmierer benötigen. Ich persönlich bin daran interessiert, eine Sprache zu schreiben, die sich gut zum Schreiben serverbasierter Anwendungen eignet.

[Während der Podiumsdiskussion brachte Guy Steele diesen Punkt ebenfalls vor und schlug zusätzlich vor, 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 vorgesehen.]

4. Eine Sprache muss zum Schreiben von Wegwerfprogrammen gut sein.

Sie wissen, was ein Wegwerfprogramm ist: etwas, das man schnell für eine begrenzte Aufgabe schreibt. Ich denke, wenn Sie sich umsehen, werden Sie feststellen, dass viele große, ernsthafte Programme als Wegwerfprogramme begannen. Es würde mich nicht überraschen, wenn die meisten Programme als Wegwerfprogramme begannen. Wenn Sie also eine Sprache erstellen möchten, die sich gut zum Schreiben von Software im Allgemeinen eignet, muss sie auch zum Schreiben von Wegwerfprogrammen geeignet sein, denn das ist das Larvenstadium der meisten Software.

5. Syntax ist mit Semantik verbunden.

Traditionell betrachtet man Syntax und Semantik als völlig getrennt. Das klingt vielleicht schockierend, aber vielleicht ist das nicht der Fall. Ich denke, dass das, was Sie in Ihrer Sprache wollen, damit zusammenhängt, wie Sie es ausdrücken.

Ich habe kürzlich mit Robert Morris gesprochen und er hat darauf hingewiesen, dass Operatorüberladung in Sprachen mit Infixsyntax ein größerer Vorteil ist. In einer Sprache mit Präfixsyntax ist jede Funktion, die Sie definieren, tatsächlich ein Operator. Wenn Sie ein Plus für einen neuen Zahlentyp definieren möchten, den Sie erfunden haben, können Sie einfach eine neue Funktion definieren, um es hinzuzufügen. Wenn Sie das in einer Sprache mit Infixsyntax tun, gibt es einen großen Unterschied zwischen der Verwendung eines überladenen Operators und einem Funktionsaufruf.

1. Neue Programmiersprachen.

In den 1970er Jahren war es in Mode, neue Programmiersprachen zu entwickeln. In letzter Zeit war das nicht mehr so. Aber ich glaube, dass serverbasierte Software neue Sprachen wieder in Mode bringen wird. Mit serverbasierter Software können Sie jede beliebige Sprache verwenden. Wenn also jemand eine Sprache entwickelt, die tatsächlich besser zu sein scheint als andere verfügbare Sprachen, wird es Leute geben, die das Risiko eingehen und sie verwenden.

2. Zeitteilung.

Richard Kelsey hat im letzten Panel diese Idee als wieder angesagt bezeichnet und ich stimme ihm voll und ganz zu. Ich (und anscheinend auch Microsoft) vermute, dass ein Großteil der Computerarbeit vom Desktop auf Remote-Server verlagert wird. Mit anderen Worten: Time-Sharing ist zurück. Und ich denke, es wird Unterstützung dafür auf Sprachebene geben müssen. Ich weiß zum Beispiel, dass Richard und Jonathan Rees viel Arbeit in die Implementierung der Prozessplanung in Scheme 48 gesteckt haben.

3. Effizienz.

Vor kurzem schien es, als seien Computer endlich schnell genug. Immer mehr hörten wir von Bytecode, was zumindest für mich bedeutet, dass wir das Gefühl haben, wir hätten Zyklen übrig. Aber ich glaube nicht, dass das bei serverbasierter Software der Fall sein wird. 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 Teiler ihrer Kapitalkosten sein.

Ich denke also, dass Effizienz eine Rolle spielen wird, zumindest bei Rechenengpässen. Besonders wichtig wird es sein, die E/A schnell durchzuführen, da serverbasierte Anwendungen eine Menge E/A durchführen.

Es könnte sich herausstellen, dass Bytecode am Ende doch kein Gewinn ist. Sun und Microsoft stehen sich derzeit in einer Art Bytecode-Kampf gegenüber. Aber sie tun es, weil Bytecode ein praktischer Ort ist, um sich in den Prozess einzufügen, und nicht, weil Bytecode an sich eine gute Idee ist. Es könnte sich herausstellen, dass dieses ganze Schlachtfeld umgangen wird. Das wäre irgendwie amüsant.

1. Kunden.

Das ist nur eine Vermutung, aber ich gehe davon aus, dass das Erfolgsmodell für die meisten Anwendungen rein serverbasiert sein wird. Software zu entwickeln, die auf der Annahme basiert, dass jeder Ihren Client hat, ist wie eine Gesellschaft zu entwickeln, die auf der Annahme basiert, dass jeder einfach ehrlich ist. Das wäre sicherlich praktisch, aber Sie müssen davon ausgehen, dass es nie passieren wird.

Ich glaube, es wird immer mehr Geräte geben, die über irgendeine Art von Internetzugang verfügen, und man wird nur davon ausgehen können, dass sie einfaches HTML und Formulare unterstützen. Werden Sie einen Browser auf Ihrem Mobiltelefon haben? Wird Ihr Palm Pilot ein Telefon haben? Wird Ihr Blackberry einen größeren Bildschirm bekommen? Werden Sie auf Ihrem Gameboy im Internet surfen können? Auf Ihrer Uhr? Ich weiß es nicht. Und ich muss es auch nicht wissen, wenn ich darauf wette, dass alles einfach auf dem Server ist. Es ist einfach viel robuster, wenn alle Gehirne auf dem Server sind.

2. Objektorientierte Programmierung.

Mir ist klar, dass das ein kontroverses Thema ist, aber ich glaube nicht, dass objektorientierte Programmierung so eine große Sache ist. Ich denke, es ist ein gutes Modell für bestimmte Arten von Anwendungen, die diese spezielle Art von Datenstruktur benötigen, wie etwa Fenstersysteme, Simulationen und CAD-Programme. Aber ich sehe nicht ein, warum es das Modell für die gesamte Programmierung sein sollte.

Ich denke, ein Grund, warum Leute in großen Unternehmen objektorientierte Programmierung mögen, ist, dass sie viel Arbeit hervorbringt. Etwas, das normalerweise beispielsweise als Liste von Ganzzahlen dargestellt werden könnte, kann jetzt als Klasse mit allen möglichen Gerüsten und allem Drum und Dran dargestellt werden.

Ein weiterer Vorteil der objektorientierten Programmierung besteht darin, dass Methoden Ihnen einige der Effekte erstklassiger Funktionen bieten. Für Lisp-Programmierer ist das jedoch nichts Neues. Wenn Sie tatsächlich erstklassige Funktionen haben, können Sie diese einfach so verwenden, wie es für die jeweilige Aufgabe angemessen ist, anstatt alles in eine Form von Klassen und Methoden zu zwängen.

Für das Sprachdesign bedeutet das meiner Meinung nach, dass man die objektorientierte Programmierung nicht zu tief einbauen sollte. Vielleicht besteht die Antwort darin, allgemeinere, grundlegendere Dinge anzubieten und die Leute die Objektsysteme, die sie wollen, als Bibliotheken entwerfen zu lassen.

3. Entwurf durch ein Komitee.

Die eigene Sprache von einem Komitee entwerfen zu lassen, ist eine große Falle, und das nicht nur aus den Gründen, die jeder kennt. Jeder weiß, dass Komitees dazu neigen, ungleichmäßige, inkonsistente Entwürfe zu produzieren. Aber ich denke, eine noch größere Gefahr besteht darin, dass sie keine Risiken eingehen. Wenn eine Person das Sagen hat, kann sie Risiken eingehen, denen ein Komitee niemals zustimmen würde.

Ist es jedoch notwendig, Risiken einzugehen, um eine gute Sprache zu entwickeln? Viele Leute vermuten vielleicht, dass man sich beim Sprachdesign ziemlich eng an die konventionellen Weisheiten halten sollte. Ich wette, das stimmt nicht. Bei allem anderen, was Menschen tun, ist der Nutzen proportional zum Risiko. Warum sollte es beim Sprachdesign anders sein?