WAS LISP ANDERS MACHTE
OriginalDezember 2001 (rev. Mai 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 entwickelte, stellte es eine radikale Abkehr von bestehenden Sprachen dar, von denen Fortran die wichtigste war.
Lisp verkörperte neun neue Ideen:
1. Konditionale. Ein Konditional ist eine if-then-else-Konstruktion. Wir halten diese heute für selbstverständlich. Sie wurden von McCarthy im Zuge der Entwicklung von Lisp erfunden . (Fortran hatte damals nur ein bedingtes goto, das eng auf dem Branch-Befehl der zugrunde liegenden Hardware basierte.) McCarthy, der im Algol-Komitee war, brachte Konditionale 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 ganze Zahlen, Zeichenfolgen usw. und haben eine wörtliche Darstellung, können in Variablen gespeichert, als Argumente übergeben werden usw.
3. Rekursion. Rekursion existierte als mathematisches Konzept natürlich schon vor Lisp, aber Lisp war die erste Programmiersprache, die es unterstützte. (Man könnte argumentieren, dass es implizit ist, wenn Funktionen zu Objekten erster Klasse gemacht werden.)
4. Ein neues Konzept von Variablen. In Lisp sind alle Variablen tatsächlich Zeiger. Werte haben Typen, nicht Variablen, und das Zuweisen oder Binden von Variablen bedeutet das Kopieren von Zeigern, nicht das, worauf sie zeigen.
5. Müllabfuhr.
6. Aus Ausdrücken bestehende Programme. Lisp-Programme sind Ausdrucksbäume, 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.
Diese Unterscheidung war in Fortran ganz natürlich, da die Sprache zeilenorientiert war (was in einer Sprache, deren Eingabeformat Lochkarten waren, nicht überraschend ist). Man konnte keine Anweisungen verschachteln. Und obwohl man Ausdrücke brauchte, damit die Mathematik funktionierte, hatte es keinen Sinn, irgendetwas anderes einen Wert zurückgeben zu lassen, da nichts darauf warten konnte.
Diese Einschränkung verschwand mit dem Aufkommen blockstrukturierter Sprachen, aber da war es schon zu spät. Die Unterscheidung zwischen Ausdrücken und Anweisungen war fest verankert. Sie verbreitete sich von Fortran über Algol zu beiden Nachkommen.
Wenn eine Sprache ausschließlich aus Ausdrücken besteht, können Sie Ausdrücke beliebig zusammenstellen. Sie können entweder sagen (mit Arc- Syntax):
(wenn foo (= x 1) (= x 2))
oder
(= x (wenn foo 1 2))
7. Ein Symboltyp. Symbole unterscheiden sich von Zeichenfolgen darin, dass Sie die Gleichheit durch Vergleichen eines Zeigers testen können.
8. Eine Notation für Code unter Verwendung von Symbolbäumen.
9. Die gesamte Sprache ist immer verfügbar. Es gibt keinen wirklichen Unterschied zwischen Lese-, Kompilier- und Laufzeit. Sie können Code während des Lesens kompilieren oder ausführen, Code während des Kompilierens lesen oder ausführen und Code zur Laufzeit lesen oder kompilieren.
Durch Ausführen von Code zur Lesedauer können Benutzer die Syntax von Lisp neu programmieren. Das Ausführen von Code zur Kompilierzeit bildet die Grundlage für Makros. Das Kompilieren zur Laufzeit bildet die Grundlage für die Verwendung von Lisp als Erweiterungssprache in Programmen wie Emacs. Und das Lesen zur Laufzeit ermöglicht Programmen die Kommunikation mithilfe von S-Ausdrücken, einer Idee, die vor Kurzem als XML neu erfunden wurde.
Als Lisp erfunden wurde, waren all diese Ideen weit entfernt von der normalen Programmierpraxis, die weitgehend von der Ende der 1950er Jahre verfügbaren Hardware bestimmt wurde.
Im Laufe der Zeit hat sich die Standardsprache, die in einer Reihe populärer Sprachen enthalten ist, allmählich in Richtung Lisp entwickelt. 1-5 sind mittlerweile weit verbreitet. 6 beginnt, im Mainstream aufzutauchen. Python hat eine Form von 7, obwohl es dafür anscheinend keine Syntax gibt. 8, das (zusammen mit 9) Lisp-Makros ermöglicht, ist bislang noch einzigartig für Lisp, vielleicht weil (a) es diese Klammern oder etwas ebenso Schlimmes erfordert und (b) man, wenn man dieses letzte Leistungsinkrement hinzufügt, nicht mehr behaupten kann, eine neue Sprache erfunden zu haben, sondern nur, einen neuen Lisp-Dialekt entwickelt zu haben ; -)
Obwohl es für heutige Programmierer nützlich ist, ist es seltsam, Lisp anhand seiner Abweichungen von den zufälligen Hilfsmitteln zu beschreiben, die andere Sprachen übernommen haben. So dachte McCarthy wahrscheinlich nicht darüber. Lisp wurde nicht entwickelt, um die Fehler von Fortran zu beheben; es entstand eher als Nebenprodukt eines Versuchs, Berechnungen zu axiomatisieren .