Loading...

WAS LISP ANDERS MACHTE

Original

December 2001 (rev. May 2002)

(Dieser Artikel entstand als Antwort auf einige Fragen auf der LL1 Mailingliste. Er ist jetzt in Revenge of the Nerds integriert.)

Als McCarthy Lisp in den späten 1950er Jahren entwarf, war es ein radikaler Bruch mit bestehenden Sprachen, von denen die wichtigste Fortran war.

Lisp verkörperte neun neue Ideen:

1. Bedingte Anweisungen. Eine bedingte Anweisung ist eine if-then-else- Konstruktion. Wir nehmen diese heute für selbstverständlich hin. Sie wurden erfunden von McCarthy im Zuge der Entwicklung von Lisp. (Fortran hatte zu dieser Zeit nur eine bedingte goto-Anweisung, die eng an die Branch-Anweisung in der zugrunde liegenden Hardware angelehnt war.) McCarthy, der im Algol-Komitee saß, brachte bedingte Anweisungen in Algol ein, von wo aus sie sich in die meisten anderen Sprachen verbreiteten.

2. Ein Funktionstyp. In Lisp sind Funktionen erstklassige Objekte - sie sind ein Datentyp wie Integer, Strings, usw. und haben eine literale Darstellung, können in Variablen gespeichert werden, können als Argumente übergeben werden, und so weiter.

3. Rekursion. Rekursion existierte als mathematisches Konzept vor Lisp natürlich, aber Lisp war die erste Programmiersprache, die sie unterstützte. (Es ist wohl implizit in der Tatsache, dass Funktionen erstklassige Objekte sind.)

4. Ein neues Konzept von Variablen. In Lisp sind alle Variablen effektiv Zeiger. Werte sind es, die Typen haben, nicht Variablen, und das Zuweisen oder Binden von Variablen bedeutet das Kopieren von Zeigern, nicht von dem, worauf sie zeigen.

5. Garbage-Collection.

6. Programme, die aus Ausdrücken bestehen. Lisp-Programme sind Bäume von Ausdrücken, von denen jeder einen Wert zurückgibt. (In einigen Lisps können Ausdrücke mehrere Werte zurückgeben.) Dies steht im Gegensatz zu Fortran und den meisten nachfolgenden Sprachen, die zwischen Ausdrücken und Anweisungen unterscheiden.

Es war natürlich, diese Unterscheidung in Fortran zu haben, weil (nicht überraschend in einer Sprache, deren Eingabeformat Lochkarten waren) die Sprache zeilenorientiert war. Man konnte Anweisungen nicht verschachteln. Und so brauchte man zwar Ausdrücke für die Mathematik, aber es gab keinen Sinn, etwas anderem einen Wert zurückgeben zu lassen, weil es nichts geben konnte, das darauf wartete.

Diese Einschränkung verschwand mit dem Aufkommen blockstrukturierter Sprachen, aber zu diesem Zeitpunkt war es zu spät. Die Unterscheidung zwischen Ausdrücken und Anweisungen war fest etabliert. Sie verbreitete sich von Fortran nach Algol und von dort zu beiden ihren Nachkommen.

Wenn eine Sprache vollständig aus Ausdrücken besteht, kann man Ausdrücke beliebig zusammensetzen. Man kann entweder (unter Verwendung der Arc Syntax)

(if foo (= x 1) (= x 2))

oder

(= x (if foo 1 2))

7. Ein Symboltyp. Symbole unterscheiden sich von Strings dadurch, dass man die Gleichheit durch Vergleich eines Zeigers testen kann.

8. Eine Notation für Code unter Verwendung von Bäumen von Symbolen.

9. Die gesamte Sprache ist immer verfügbar. Es gibt keine wirkliche Unterscheidung zwischen Lesezeit, Kompilierzeit und Laufzeit. Man kann Code während des Lesens kompilieren oder ausführen, Code lesen oder ausführen während des Kompilierens und Code zur Laufzeit lesen oder kompilieren.

Das Ausführen von Code zur Lesezeit ermöglicht es Benutzern, die Syntax von Lisp neu zu programmieren; das Ausführen von Code zur Kompilierzeit ist die Grundlage für Makros; das Kompilieren zur Laufzeit ist die Grundlage für die Verwendung von Lisp als Erweiterungssprache in Programmen wie Emacs; und das Lesen zur Laufzeit ermöglicht es Programmen, über S-Ausdrücke zu kommunizieren, eine Idee, die kürzlich als XML wiederentdeckt wurde.

Als Lisp zum ersten Mal erfunden wurde, waren all diese Ideen weit entfernt von der gewöhnlichen Programmierpraxis, die weitgehend von der in den späten 1950er Jahren verfügbaren Hardware diktiert wurde.

Im Laufe der Zeit hat sich die Standardsprache, verkörpert in einer Reihe von populären Sprachen, allmählich in Richtung Lisp entwickelt. 1-5 sind jetzt weit verbreitet. 6 beginnt im Mainstream aufzutauchen. Python hat eine Form von 7, obwohl es keine Syntax dafür zu geben scheint. 8, das (mit 9) Lisp-Makros ermöglicht, ist bisher noch einzigartig für Lisp, vielleicht weil (a) es diese Klammern erfordert, oder etwas ebenso Schlechtes, und (b) wenn man diesen letzten Leistungsschub hinzufügt, kann man nicht mehr behaupten, eine neue Sprache erfunden zu haben, sondern nur einen neuen Lisp-Dialekt entworfen zu haben ; -)

Obwohl es für heutige Programmierer nützlich ist, ist es seltsam, Lisp in Bezug auf seine Abweichung von den zufälligen Behelfen zu beschreiben, die andere Sprachen übernommen haben. Das war wahrscheinlich nicht, wie McCarthy sich das vorgestellt hat. Lisp wurde nicht entworfen, um die Fehler in Fortran zu beheben; es entstand eher als Nebenprodukt eines Versuchs, die Berechnung zu axiomatisieren.