Lisp (Programmiersprache)

Lispeln
Lisp logo.svg
Paradigma Multi-Paradigma: funktional, prozedural, reflektierend, Meta
Entworfen von John McCarthy
Entwickler Steve Russell, Timothy P. Hart und Mike Levin
Erstmals erschienen 1958; Vor 64 Jahren
Disziplin tippen Dynamisch, stark
Dialekte
Beeinflusst von
IPL
Beeinflusst

Lispeln (historisch LISPELN) ist eine Familie von Programmiersprachen mit einer langen Geschichte und einer unverwechselbaren, voll und ganz Klammern Präfixnotation.[3] Ursprünglich im Jahr 1958 angegeben, ist Lisp das zweitälteste Programmiersprache auf hoher Ebene immer noch in allgemeinem Gebrauch. Nur Forran ist älter, um ein Jahr.[4][5] Lisp hat sich seit seinen frühen Tagen und vielen verändert Dialekte haben über seine Geschichte existiert. Heute sind die bekanntesten LISP-Dialekte im Allgemeinen in der Lage Schläger, Common Lisp, Planen, und Clojure.

Lisp wurde ursprünglich als praktisch geschaffen Mathematische Notation zum Computerprogramme, beeinflusst von (wenn auch nicht ursprünglich abgeleitet von)[6] die Notation von Alonzo -Kirche's Lambda -Kalkül. Es wurde schnell die bevorzugte Programmiersprache für künstliche Intelligenz (AI) Forschung.[7] Als eine der frühesten Programmiersprachen war LISP -Pionier vieler Ideen in Informatik, einschließlich Baumdatenstrukturen, Automatisches Speichermanagement, Dynamisches Typing, Bedingungen, Funktionen höherer Ordnung, Rekursion, das Selbsthost-Compiler,[8] und die Read -E -druck -Schleife.[9]

Der Name LISPELN stammt aus "Listenprozessor".[10] Verlinkte Listen sind einer von Lisps Major Datenstrukturenund Lisp Quellcode ist aus Listen. Daher können Lisp -Programme den Quellcode als Datenstruktur manipulieren und die Angaben zur Verfügung stellen Makro Systeme, mit denen Programmierer neue Syntax oder neue erstellen können Domänenspezifische Sprachen eingebettet in Lisp.

Die Austauschbarkeit von Code und Daten ergibt die sofort erkennbare Syntax. Alle Programmcode werden als geschrieben als S-Expressionenoder klammernte Listen. Ein Funktionsaufruf oder ein syntaktisches Formular wird als Liste zuerst mit der Funktion oder dem Namen des Bedieners und den folgenden Argumenten geschrieben. Zum Beispiel eine Funktion f Das erfordert drei Argumente als als (f arg1 arg2 arg3).

Geschichte

John McCarthy entwickelte Lisp 1958, als er bei der war Massachusetts Institute of Technology (MIT). McCarthy veröffentlichte sein Design in einem Papier in Kommunikation der ACM 1960 mit dem Titel "rekursive Funktionen symbolischer Ausdrücke und deren Berechnung nach Machine, Teil I".[11] Er zeigte, dass man mit ein paar einfachen Betreibern und einer Notation für anonyme Funktionen, die aus der Kirche geliehen wurden, a bauen kann Turing-Complete Sprache für Algorithmen.

Informationsverarbeitungssprache war der erste Ai Die Sprache von 1955 oder 1956 und bereits viele der Konzepte wie Listenverarbeitung und Rekursion enthielt, die in LISP verwendet wurden.

McCarthys ursprüngliche Notation verwendete Klammer "M-Expressionen"Das würde übersetzt werden S-Expressionen. Als Beispiel die M-Expression car[cons[A,B]] entspricht der S-Expression (car (cons A B)). Sobald LISP implementiert war, entschieden sich die Programmierer schnell für die Verwendung von S-Expressionen, und M-Expressionen wurden aufgegeben. M-Expressionen tauchten wieder mit kurzlebigen Versuchen von auf MLISP[12] von Horace Enea und CGOL durch Vaughan Pratt.

Lisp wurde zuerst implementiert von Steve Russell auf an IBM 704 Computer verwendet geschlagene Karten.[13] Russell hatte McCarthys Zeitung gelesen und erkannt (zu McCarthys Überraschung), dass der Lisp bewerten Funktion könnte in implementiert werden in Maschinensprache.

Nach McCarthy:[14]

Steve Russell sagte, schau, warum programme ich das nicht programme bewerten... und ich sagte zu ihm, ho, ho, du verwirrt die Theorie mit der Praxis, das bewerten ist zum Lesen vorgesehen, nicht zum Computer. Aber er ging weiter und tat es. Das heißt, er zusammengestellt das bewerten in meinem Papier in IBM 704 Maschinencode, Behebung Käferund dann als Lisp -Dolmetscher beworben, was es sicherlich war. Zu diesem Zeitpunkt hatte Lisp im Wesentlichen die Form, die es heute hat ...

Das Ergebnis war eine funktionierende Lisp Dolmetscher Dies könnte verwendet werden, um Lisp -Programme auszuführen oder ordnungsgemäß zu "bewerten Lisp -Ausdrücke".

Zwei Assemblersprachenmakros für die IBM 704 wurde die primitiven Operationen für die Zersetzung von Listen: car (Inhalt des Adressteils des Registers Nummer) und cdr (Inhalt des Decrement -Teils des Registers Nummer),[15] wo sich "Register" bezieht Register des Computers Zentrale Verarbeitungseinheit (ZENTRALPROZESSOR). Lisp -Dialekte verwenden noch immer car und cdr (/kːr/ und /ˈkʊdər/) für die Operationen, die das erste Element in einer Liste bzw. den Rest der Liste zurückgeben.

Der erste komplette Lisp -Compiler, der in LiSP geschrieben wurde, wurde 1962 von Tim Hart und Mike Levin am MIT implementiert und konnte durch einfach vorhandene LISP -Interpreter kompiliert werden, um den Compiler -Code zu interpretieren und produzieren Maschinensprache Ausgabe kann mit einer 40-fachen Geschwindigkeitsverbesserung gegenüber dem des Interpreters ausgeführt werden.[16] Dieser Compiler führte das LISP -Modell von vor Inkrementelle Zusammenstellung, in denen kompilierte und interpretierte Funktionen frei vermischen können. Die in Hart und Levins Memo verwendete Sprache ist dem modernen Lisp -Stil viel näher als McCarthys früherer Code.

Müllsammlung Routinen wurden vor 1962 von Daniel Edwards Daniel Edwards von MIT entwickelt.[17]

In den 1980er und 1990er Jahren wurde große Anstrengungen unifiziert, um die Arbeit an neuen Lisp -Dialekten zu vereinen (hauptsächlich Nachfolger zu MacLisp wie zum Beispiel Zetalisp und NIL (neue Implementierung von Lisp) in eine einzelne Sprache. Die neue Sprache, Common Lisp, war etwas kompatibel mit den von es ersetzten Dialekten (das Buch Gemeinsam lispeln die Sprache stellt die Kompatibilität verschiedener Konstrukte fest). Im Jahr 1994, Ansi veröffentlichte den gemeinsamen Lisp-Standard "ANSI X3.226-1994 Informationstechnologie-Programmiersprache Common Lisp".

Zeitleiste

1955 1960 1965 1970 1975 1980 1985 1990 1995 2000 2005 2010 2015 2020
Lisp 1, 1,5, Lisp 2(verlassen)
 MacLisp
 Interisp
 Mdl
 Lisp Machine Lisp
 Planen R5rs R6rs R7Rs klein
 NULL
ZIL (Zork Implementierungssprache)
 Franz Lisp
 Common Lisp
 Le lisp
 MIT -Schema
 T
 Chez Schema
 EMACS Lisp
 Autolisp
 Picolisp
 EULISP
 ISLISP
 OpenLisp
 PLT -Schema  Schläger
 Gnu Guile
 Visual Lisp
 Clojure
 Bogen
 Lfe
 Hy

Verbindung zur künstlichen Intelligenz

Seit Beginn war Lisp eng mit dem verbunden mit dem künstliche Intelligenz Forschungsgemeinschaft, insbesondere auf PDP-10[18] Systeme. Lisp wurde als Implementierung der Sprache verwendet Mikroplaner, das im berühmten KI -System verwendet wurde Shrdlu. In den 1970er Jahren, als KI -Forschung kommerzielle Ableger hervorbrachte, wurde die Leistung bestehender Lisp -Systeme zu einem wachsenden Problem, da die Programmierer mit den Leistungsauswirkungen der verschiedenen Techniken und Auswahlmöglichkeiten, die an der Implementierung von LISP beteiligt waren, vertraut sein mussten.[19]

Genealogie und Varianten

In seiner sechzigjährigen Geschichte hat Lisp viele Variationen zum Kernthema einer S-Expressionssprache hervorgebracht. Darüber hinaus kann jeder gegebene Dialekt mehrere Implementierungen haben - zum Beispiel gibt es mehr als ein Dutzend Implementierungen von Common Lisp.

Unterschiede zwischen Dialekten können sehr sichtbar sein - zum Beispiel verwendet Common Lisp das Schlüsselwort Defun Um eine Funktion zu nennen, aber das Schema verwendet definieren.[20] Innerhalb eines standardisierten Dialekts unterstützen die konformen Implementierungen jedoch dieselbe Kernsprache, jedoch mit unterschiedlichen Erweiterungen und Bibliotheken.

Historisch bedeutende Dialekte

  • Lisp 1[21] - Erste Implementierung.
  • Lisp 1.5[22] - Erste weit verbreitete Version, die von McCarthy und anderen am MIT entwickelt wurde. So benannt, weil es mehrere Verbesserungen am ursprünglichen "LISP 1" -Dolmetscher enthielt, aber keine wichtige Umstrukturierung wie die geplanten war Lisp 2 wäre.
  • Stanford Lisp 1.6[23] - Dies war ein Nachfolger von LISP 1.5, der am entwickelt wurde Stanford AI Labund weit verbreitet zu PDP-10 Systeme, die das ausführen Tops-10 Betriebssystem. Es wurde von MacLisp und Interisp veraltet.
  • MacLisp[24] - für MITs entwickelt Projekt MAC, MacLisp ist ein direkter Nachkomme von LISP 1.5. Es lief auf der PDP-10 und Mehrheit Systeme. MacLisp wurde später als MacLisp genannt und wird oft als MacLisp bezeichnet. Der "Mac" in MacLisp hängt auch nicht mit Apple zusammen Macintosh Noch zu McCarthy.
  • Interisp[25] - entwickelt bei BBN Technologies Für PDP-10-Systeme, die das ausführen TEMEX -Betriebssystemspäter als "West Coast" Lisping für die Xerox-Lisp-Maschinen als Interisp-D. Eine kleine Version namens "Interisp 65" wurde für die veröffentlicht 6502-basierend Atari 8-Bit-Familie Computerlinie. MACLISP und Interspisp waren seit einiger Zeit starke Konkurrenten.
  • Franz Lisp - ursprünglich a Universität von Kalifornien, Berkeley Projekt; später entwickelt von Franz Inc. Der Name ist eine humorvolle Verformung des Namens "Franz Liszt"und bezieht sich nicht auf Allegro Common Lisp, Der Dialekt von Common Lisp von Franz Inc. in den letzten Jahren.
  • Xlisp, die Autolisp war basierend auf.
  • Standard Lisp und Tragbares Standard -LISP wurden weit verbreitet und portiert, insbesondere mit dem Computer -Algebra -System reduziert.
  • Zetalisp, auch als Lisp Machine Lisp bezeichnet - verwendet auf dem Lisp -Maschinen, direkter Nachkomme von MacLisp. Zetalisp hatte einen großen Einfluss auf das gemeinsame LISP.
  • Lelisp ist ein französischer Lisp -Dialekt. Einer der Ersten Schnittstellenbauer (SOS -Schnittstelle genannt[26]) wurde in lelisp geschrieben.
  • Planen (1975).[27]
  • Common Lisp (1984), wie beschrieben von Gemeinsam lispeln die Sprache - Eine Konsolidierung mehrerer unterschiedlicher Versuche (Zetalisp, Spice Lisp, NULL, und S-1 Lisp) Nachfolgerdialekten erstellen[28] zu maclisp, mit materiellen Einflüssen auch aus dem Schema -Dialekt. Diese Version von Common Lisp war für weitreichende Plattformen erhältlich und wurde von vielen als a akzeptiert De facto Standard[29] bis zur Veröffentlichung von ANSI Common Lisp (ANSI X3.226-1994). Zu den am weitesten verbreiteten Sub-Dialekten des gemeinsamen Lisp sind Stahlbank Common Lisp (SBCL), CMU Common Lisp (CMU-CL), Clozure OpenMCL (nicht mit Clojure verwechselt werden!), GNU Clisp und spätere Versionen von Franz Lisp; Alle von ihnen haften an den späteren ANSI -Cl -Standard (siehe unten).
  • Dylan war in seiner ersten Version eine Mischung aus Schema mit dem gemeinsamen Lisp -Objektsystem.
  • EULISP -Versuchen Sie, ein neues effizientes und aufgeräumtes Lisp zu entwickeln.
  • ISLISP -Versuchen Sie, ein neues effizientes und aufgeräumtes Lisp zu entwickeln. Standardisiert wie ISO/IEC 13816: 1997[30] und später als ISO/IEC 13816: 2007 überarbeitet:[31] Informationstechnologie - Programmiersprachen, ihre Umgebungen und Systemsoftware -Schnittstellen - Programmiersprache ISLISP.
  • IEEE Planen - IEEE Standard, 1178–1990 (R1995).
  • Ansi Common Lisp - ein American National Standards Institute (ANSI) Standard für Common Lisp, erstellt vom Unterausschuss X3j13, Chartered[32] zunächst Common Lisp: Die Sprache als Basisdokument und durch eine Öffentlichkeit zu arbeiten Konsens Prozess, um Lösungen für gemeinsame Probleme von zu finden Portabilität von Programmen und Kompatibilität von gemeinsamen LISP -Implementierungen. Obwohl formell ein ANSI -Standard, wurde und wird die Implementierung, den Verkauf, die Verwendung und der Einfluss von ANSI Common Lisp weltweit gesehen.
  • ACL2 oder "eine Rechenlogik für anwendbares gemeinsames Lisp", eine anwendbare (seitlich effektfreie) Variante von gemeinsamem Lisp. ACL2 ist sowohl eine Programmiersprache, die Computersysteme modellieren kann, als auch ein Tool, um die Eigenschaften dieser Modelle zu beweisen.
  • Clojure, ein neuer Dialekt von Lisp, der dem zusammenfasst Java virtuelle Maschine und hat einen besonderen Schwerpunkt auf Parallelität.
  • Spielorientierte Montage Lisp (oder Ziel) ist eine von Andy Gavin und dem entwickelte Videospiel -Programmiersprache Jak und Daxter Team bei Frecher Hund. Es wurde mit Allegro Common Lisp geschrieben und zur Entwicklung des gesamten verwendet Jak- und Daxter -Spielserie von Spielen.
  • Chialisp, ein hochrangiger Dialekt, der zu CLVM zusammenfasst, der On-Chain-Programmierumgebung in Chia-Blockchain

2000 zu präsentieren

Nach etwas zurückgegangen in den neunziger Jahren hat LiSP nach 2000 ein Wiederaufleben von Interesse erlebt. Common Lisp, Planen, EMACS Lisp, Clojure, und Schlägerund beinhaltet die Entwicklung neuer tragbarer Bibliotheken und Anwendungen.

Viele neue Lisp -Programmierer wurden von Schriftstellern wie inspiriert wie Paul Graham und Eric S. Raymond Um eine Sprache zu verfolgen, die andere als veraltet angesehen werden. Neue Lisp-Programmierer beschreiben die Sprache häufig als eine Augenöffnungserfahrung und behaupten, wesentlich produktiver zu sein als in anderen Sprachen.[33] Diese Erhöhung des Bewusstseins kann dem "kontrastiert werden"AI Winter"Und Lisps kurzer Gewinn Mitte der neunziger Jahre.[34]

Ab 2010Es gab elf aktiv gehaltene gemeinsame LISP -Implementierungen.[35] Scieneer Common Lisp ist eine neue kommerzielle Implementierung, die von CMUCL mit einer ersten Veröffentlichung im Jahr 2002 gegabelt wurde.

Das Open Source Community hat eine neue unterstützende Infrastruktur geschaffen: Cliki ist ein Wiki, das gemeinsame LISP -verwandte Informationen sammelt. Das gemeinsame Lisp -Verzeichnis listet Ressourcen auf. IRC Bot Planet Lisp geschrieben in LISP) und sammelt den Inhalt verschiedener Lisp-bezogene Blogs, auf LispForum-Benutzern diskutieren Lispjobs ein Service für die Ankündigung von Stellenangeboten und es gibt einen wöchentlichen Nachrichtenservice. Wöchentliche Lisp -Nachrichten. Common-lisp.net ist eine Hosting -Site für Open -Source -Common Lisp -Projekte. QuickLisp ist Bibliotheksmanager für Common Lisp.

Fünfzig Jahre Lisp (1958–2008) wurden bei Lisp50@oopsla gefeiert.[36] In Boston, Vancouver und Hamburg gibt es regelmäßige lokale Benutzerversammlungen. Weitere Veranstaltungen sind das European Common Lisp Meeting, das europäische Lisp -Symposium und eine internationale Lisp -Konferenz.

Die Scheme -Community unterhält aktiv Über zwanzig Implementierungen. In den 2000er Jahren (Jahrzehnt) wurden mehrere bedeutende neue Implementierungen (Hühnchen, Gambit, Gauche, Ikarus, Diebstahl, Ypsilon) entwickelt. Die überarbeiteten5 Bericht über das algorithmische Sprachschema[37] Der Standard des Schemas wurde in der Scheme -Community weithin akzeptiert. Das Schemeanfragen zur Implementierung Process hat viele Quasi -Standardbibliotheken und Erweiterungen für Schema erstellt. Die Benutzergemeinschaften von individuellen Schema -Implementierungen wachsen weiter. Ein neuer Sprachstandardisierungsprozess wurde 2003 gestartet und führte zum r6RS -Schema Standard im Jahr 2007. Der akademische Einsatz des Programms für das Unterrichten von Informatik scheint etwas zurückgegangen zu sein. Einige Universitäten verwenden in ihren Informatik -Einführungskursen kein Schema mehr.[38][39] MIT verwendet jetzt Python anstelle von Schema für seinen Student Informatik Programm und MITX massiven Open Online -Kurs.[40][41]

Es gibt mehrere neue LISP -Dialekte: Bogen, Hy, Nu, Liskell und Lfe (Erlang mit Lisp -aromatisiert). Der Parser für Julia wird in femtolisp implementiert, ein Dialekt von Planen (Julia ist von Schema inspiriert, was wiederum ein Lisp -Dialekt ist).

Im Oktober 2019, Paul Graham veröffentlicht Eine Spezifikation für Bel"Ein neuer Dialekt von Lisp."

Hauptdialekte

Common Lisp und Planen darstellen zwei Hauptströme der Lisp -Entwicklung. Diese Sprachen verkörpern erheblich unterschiedliche Designentscheidungen.

Common Lisp ist ein Nachfolger von MacLisp. Die primären Einflüsse waren Lisp Machine Lisp, MacLisp, NULL, S-1 Lisp, Spice Lispund Schema.[42] Es verfügt über viele Funktionen von Lisp Machine Lisp (ein großer Lisp -Dialekt, der zum Programmieren verwendet wird Lisp -Maschinen), wurde jedoch so konzipiert, dass sie auf jedem Personalcomputer oder einer Arbeitsstation effizient implementierbar sind. Common Lisp ist eine allgemeine Programmiersprache und verfügt daher über einen großen Sprachstandard, der viele integrierte Datentypen, Funktionen, Makros und andere Sprachelemente sowie ein Objektsystem (ein Objektsystem (Gemeinsames Lisp -Objektsystem). Common Lisp hat auch bestimmte Merkmale aus dem Schema ausgeliehen, wie z. lexikaler Scoping und lexikalische Schließungen. Gemeinsame LiSP -Implementierungen stehen zur Verfügung, um verschiedene Plattformen anzusprechen, wie sie Llvm,[43] das Java virtuelle Maschine,[44] X86-64, Powerpc, Alpha, Arm, Motorola 68000 und MIPS,[45] und Betriebssysteme wie Windows, MacOS, Linux, Solaris, FreeBSD, NetBSD, OpenBSD, Dragonfly BSD und Heroku.[46]

Das Schema ist ein statisch geschriebener und ordnungsgemäß schwanzrekursiver Dialekt der von der LiSP-Programmiersprache erfundenen von erfundenen von erfunden Guy L. Steele, Jr. und Gerald Jay Sussman. Es wurde so konzipiert, dass es außergewöhnlich klare und einfache Semantik und wenige verschiedene Möglichkeiten zur Bildung von Ausdrücken aufweist. Etwa ein Jahrzehnt früher als das gemeinsame Lisps entworfen, Planen ist ein minimalistischeres Design. Es hat viel kleinere Standardfunktionen, jedoch mit bestimmten Implementierungsfunktionen (wie z. Schwanzoptimierung und voll Kontinuationen) Nicht in gemeinsamer Lisp angegeben. Eine Vielzahl von Programmierparadigmen, einschließlich Imperativ-, Funktions- und Nachrichtenübergabestilen, finden einen bequemen Ausdruck im Schema. Das Programm entwickelt sich weiter mit einer Reihe von Standards (überarbeitetn Bericht über das algorithmische Sprachschema) und eine Reihe von einer Reihe von Schemeanfragen zur Implementierung.

Clojure ist ein aktueller LISP -Dialekt, der hauptsächlich auf das abzielt Java virtuelle Maschine, und die Gemeinsame Sprachlaufzeit (Clr), die Python VM, der Ruby VM Yarvund zusammenstellen zu JavaScript. Es ist eine pragmatische allgemeine Sprache. Clojure zieht beträchtliche Einflüsse aus Haskell und legt eine sehr starke Betonung der Unveränderlichkeit.[47] Clojure bietet Zugriff auf Java -Frameworks und Bibliotheken mit optionalen Typ -Tipps und Geben Sie Inferenz einDaher kann das Aufrufen von Java Reflexion vermeiden und schnelle primitive Operationen ermöglichen. Clojure ist nicht so konzipiert, dass sie mit anderen Lisp -Dialekten rückwärts kompatibel ist.[48]

Ferner werden Lisp -Dialekte als verwendet Skriptsprachen in vielen Anwendungen mit dem bekanntesten Wesen EMACS Lisp in dem EMACs Editor, Autolisp und später Visual Lisp in Autocad, Nyquist in Unverfrorenheitund Schema in Lilienteich. Die potenzielle geringe Größe eines nützlichen Schemas -Dolmetschers macht es besonders beliebt für eingebettete Skripten. Beispiele beinhalten SIOD und Tinyschemebeide, die erfolgreich in die eingebettet wurden Gimp Bildprozessor unter dem generischen Namen "Skript-Fu".[49] Librep, ein Lisp -Dolmetscher von John Harper, der ursprünglich auf dem basiert EMACS Lisp Sprache, wurde in die eingebettet Sägefisch Fenstermanager.[50]

Standardisierte Dialekte

LISP hat offiziell standardisierte Dialekte: R6RS -Schema, R7RS -Schema, IEEE -Schema,[51] ANSI Common Lisp und iso ISLISP.

Sprachinnovationen

LISP war die erste Sprache, in der die Struktur des Programmcodes treu und direkt in einer Standarddatenstruktur dargestellt wird - eine Qualität, die viel später genannt wird. "Homoikonizität" Makros und Metaccircular -Bewertung.

Eine bedingte Verwendung eines wenn - dann - ELSE Syntax wurde von McCarthy in einem FORTRAN -Kontext erfunden. Er schlug seine Aufnahme in vor Algol, aber es wurde nicht zu einem Teil der Algol 58 Spezifikation. Für Lisp verwendete McCarthy die allgemeine Kond-Struktur.[52] Algol 60 nahm auf wenn - dann - ELSE und populär es.

LISP tief beeinflusst Alan Kay, der Leiter des Forschungsteams, das sich entwickelte Smalltalk bei Xerox Parc; und wiederum wurde Lisp von SmallTalk beeinflusst, wobei spätere Dialekte in den 1970er Jahren objektorientierte Programmierfunktionen (Vererbungsklassen, Einkapselung von Instanzen, Nachrichtenübergang usw.) anwenden. Das Flavors Objektsystem führte das Konzept von vor Mehrfacherbe und die mischen. Das Gemeinsames Lisp -Objektsystem bietet mehrere Vererbung, Multimethods mit Mehrfachversandund erstklassig generische Funktioneneine flexible und kraftvolle Form von ergeben Dynamischer Versand. Es wurde als Vorlage für viele nachfolgende Lisp (einschließlich Planen) Objektsysteme, die häufig über a implementiert werden MetaObject -Protokoll, a reflektierend MetaCircular Design in dem das Objektsystem in Bezug auf sich selbst definiert ist: Lisp war nur die zweite Sprache nach SmallTalk (und ist immer noch eine der wenigen Sprachen), um ein solches MetaObject -System zu besitzen. Viele Jahre später schlug Alan Kay vor, dass aufgrund des Zusammenflusss dieser Merkmale nur SmallTalk und Lisp als ordnungsgemäß konzipierte objektorientierte Programmiersysteme angesehen werden könnten.[53]

Lisp stellte das Konzept von vor Automatische Müllsammlung, in dem das System die Haufen Auf der Suche nach ungenutzter Erinnerung. Fortschritte in modernen hoch entwickelten Müllsammlungsalgorithmen wie der Sammlung von Müll in der Generation wurden durch die Verwendung in LiSP stimuliert.[54]

Edsger W. Dijkstra in seiner 1972 Turing Award Vorlesung sagte:

Mit ein paar sehr grundlegenden Prinzipien auf der Grundlage hat es [Lisp] eine bemerkenswerte Stabilität gezeigt. Außerdem war Lisp der Spediteur für eine beträchtliche Anzahl von unserer anspruchsvollsten Computeranwendungen. LISP wurde scherzhaft als "die intelligenteste Möglichkeit, einen Computer zu missbrauchen" beschrieben. Ich denke, diese Beschreibung ist ein großes Kompliment, weil sie den vollen Geschmack der Befreiung überträgt: Es hat eine Reihe unserer begabtesten Mitmenschen bei der Denkweise zuvor unmöglicher Gedanken unterstützt.[55]

Vor allem aufgrund seiner Ressourcenanforderungen in Bezug auf frühe Computerhardware (einschließlich früher Mikroprozessoren) wurde LiSP außerhalb der nicht so beliebt Ai Gemeinschaft als Forran und die Algol-Deszeniert C Sprache. Aufgrund seiner Eignung für komplexe und dynamische Anwendungen genießt Lisp eine Wiederbelebung des Volksinteresses an den 2010er Jahren.[56]

Syntax und Semantik

Notiz: Beispiele dieses Artikels sind in geschrieben Common Lisp (Obwohl die meisten auch in gültig sind in Planen).

Symbolische Ausdrücke (S-Expressions)

Lisp ist ein Ausdrucksorientierte Sprache. Im Gegensatz zu den meisten anderen Sprachen wird keine Unterscheidung zwischen "Ausdrücken" und ohne Unterscheidung getroffen "Aussagen";[zweifelhaft ] Alle Code und Daten werden als Ausdrücke geschrieben. Wenn ein Ausdruck ist bewertetEs erzeugt einen Wert (in gemeinsamer LISP, möglicherweise mehrere Werte), der dann in andere Ausdrücke eingebettet werden kann. Jeder Wert kann jeder Datentyp sein.

McCarthys Papier von 1958 führte zwei Arten von Syntax vor: Symbolische Ausdrücke (S-Expressionen, sexps), die die interne Darstellung von Code und Daten widerspiegeln; und Meta -Ausdrücke (M-Expressionen), die Funktionen von S-Expressionen ausdrücken. M-Expressionen fanden nie Gunst, und fast alle LISPs verwenden heute S-Expressions, um sowohl Code als auch Daten zu manipulieren.

Die Verwendung von Klammern ist die unmittelbar offensichtlichste Unterschiede von LiSP zu anderen Familien der Programmiersprache. Infolgedessen haben die Schüler längst Lisp -Spitznamen gegeben, z. In dummen Klammern verloren, oder Viele irritierende überflüssige Klammern.[57] Die S-Expressionssyntax ist jedoch auch für einen Großteil der LISP-Macht verantwortlich: Die Syntax ist einfach und konsistent, was die Manipulation durch Computer erleichtert. Die Syntax von Lisp ist jedoch nicht auf herkömmliche Klammern -Notation beschränkt. Es kann erweitert werden, um alternative Notationen einzuschließen. Zum Beispiel ist XMLISP eine gemeinsame Lisp -Erweiterung, die die verwendet MetaObject -Protokoll Um S-Expressionen in die erweiterbare Markup-Sprache zu integrieren (Xml).

Das Vertrauen in Ausdrücke verleiht der Sprache große Flexibilität. Weil LISP Funktionen sind als Listen geschrieben, sie können genau wie Daten verarbeitet werden. Dies ermöglicht das einfache Schreiben von Programmen, die andere Programme manipulieren (Metaprogrammierung). Viele LiSP -Dialekte nutzen diese Funktion mithilfe von Makrosystemen, die die Erweiterung der Sprache fast ohne Grenzen ermöglichen.

Listen

Eine Lisp -Liste wird mit ihren Elementen geschrieben, die durch getrennt sind Whitespaceund umgeben von Klammern. Zum Beispiel, (1 2 foo) ist eine Liste, deren Elemente die drei sind Atome 1, 2, und foo. Diese Werte werden implizit getippt: Sie sind jeweils zwei Ganzzahlen und ein lispspezifischer Datentyp, der als "Symbol" bezeichnet wird, und müssen nicht als solche deklariert werden.

Die leere Liste () wird auch als spezielles Atom dargestellt nil. Dies ist die einzige Einheit in LISP, die sowohl ein Atom als auch eine Liste ist.

Ausdrücke werden als Listen geschrieben, wobei sie verwendet werden Präfixnotation. Das erste Element in der Liste ist der Name einer Funktion, der Name eines Makros, eines Lambda -Ausdrucks oder der Name eines "Spezialoperators" (siehe unten). Der Rest der Liste sind die Argumente. Zum Beispiel die Funktion list Gibt seine Argumente als Liste zurück, also den Ausdruck

 (aufführen 1 2 (zitieren Foo)) 

bewertet die Liste (1 2 foo). Das "Zitat" vor dem foo Im vorhergehenden Beispiel befindet sich ein "Spezialoperator", der sein Argument zurückgibt, ohne es zu bewerten. Alle nicht zahlten Ausdrücke werden rekursiv bewertet, bevor der einschließende Ausdruck bewertet wird. Zum Beispiel,

 (aufführen 1 2 (aufführen 3 4)) 

bewertet die Liste (1 2 (3 4)). Beachten Sie, dass das dritte Argument eine Liste ist. Listen können verschachtelt werden.

Betreiber

Arithmetische Operatoren werden ähnlich behandelt. Der Ausdruck

 (+ 1 2 3 4) 

bewertet bis 10. das Äquivalent unter Infixnotation wäre "1 + 2 + 3 + 4".

LISP hat keine Vorstellung von Betreibern, wie in von Algol abgeleiteten Sprachen implementiert. Arithmetische Operatoren in Lisp sind Variadische Funktionen (oder N-Ary), in der Lage, eine beliebige Anzahl von Argumenten aufzunehmen. Ein C-Style '++' Inkrementoperator wird manchmal unter dem Namen implementiert INCF Syntax geben

 (INCF x) 

gleichwertig (setq x (+ x 1))den neuen Wert von zurückgeben x.

"Spezialoperatoren" (manchmal als "Spezialformulare" bezeichnet) liefern Lisps Kontrollstruktur. Zum Beispiel der Spezialbetreiber if nimmt drei Argumente. Wenn das erste Argument nicht nil ist, bewertet es das zweite Argument; Ansonsten bewertet es das dritte Argument. Somit der Ausdruck

 (wenn Null  (aufführen 1 2 "Foo")  (aufführen 3 4 "Bar")) 

bewertet (3 4 "bar"). Dies wäre natürlich nützlicher, wenn ein nicht trivialer Ausdruck anstelle von ersetzt worden wäre nil.

Lisp bietet auch logische Operatoren und, oder und nicht. Das und und oder Betreiber tun dies Kurzschlussbewertung und wird ihr erstes Nil- bzw. Nicht-Nil-Argument zurückgeben.

 (oder (und "Null" Null "noch nie") "James" 'Aufgabe 'Zeit) 

wird zu "James" bewerten.

Lambda -Ausdrücke und Funktionsdefinition

Ein weiterer besonderer Betreiber, lambda, wird verwendet, um Variablen an Werte zu binden, die dann innerhalb eines Expression bewertet werden. Dieser Bediener wird auch verwendet, um Funktionen zu erstellen: die Argumente an Argumente lambda sind eine Liste von Argumenten und der Ausdruck oder die Ausdrücke, auf die die Funktion bewertet wird (der zurückgegebene Wert ist der Wert des letzten Ausdrucks, der bewertet wird). Der Ausdruck

 (Lambda (arg) (+ arg 1)) 

bewertet eine Funktion, die bei der Anwendung ein Argument annimmt arg und gibt die Nummer eins mehr als dieses Argument zurück. Lambda -Ausdrücke werden nicht anders als benannte Funktionen behandelt; Sie werden auf die gleiche Weise angerufen. Daher der Ausdruck

 ((Lambda (arg) (+ arg 1)) 5) 

bewertet 6. Hier führen wir eine Funktionsanwendung durch: Wir führen die aus Anonyme Funktion indem Sie den Wert 5 an ihn weitergeben.

Benannte Funktionen werden erstellt, indem ein Lambda -Ausdruck in einem Symbol unter Verwendung des Defun -Makros gespeichert wird.

 (Defun Foo (a b c d) (+ a b c d)) 

(defun f (a) b...) definiert eine neue Funktion namens namens f in der globalen Umgebung. Es ähnelt konzeptionell dem Ausdruck:

 (setf (FDEFINITION 'f) #'(Lambda (a) (Block f b...))) 

wo setf ist ein Makro, das verwendet wird, um den Wert des ersten Arguments festzulegen fdefinition 'f zu einem neuen Funktionsobjekt. fdefinition ist eine globale Funktionsdefinition für die namige Funktion f. #' ist eine Abkürzung für function Spezialbetreiber, Rückgabe eines Funktionsobjekts.

Atome

Im Original LISPELN Es gab zwei grundlegende Datentypen: Atome und Listen. Eine Liste war eine endlich geordnete Reihenfolge von Elementen, bei denen jedes Element entweder ein Atom oder eine Liste ist, und ein Atom war a Nummer oder ein Symbol. Ein Symbol war im Wesentlichen ein einzigartiger benannter Element, der als ein geschrieben wurde alphanumerisch Saite in Quellcodeund verwendet entweder als variabler Name oder als Datenelement in Symbolische Verarbeitung. Zum Beispiel die Liste (FOO (BAR 1) 2) Enthält drei Elemente: das Symbol FOO, Die Liste (BAR 1)und die Nummer 2.

Der wesentliche Unterschied zwischen Atomen und Listen bestand darin, dass Atome unveränderlich und einzigartig waren. Zwei Atome, die an verschiedenen Stellen im Quellcode erschienen, aber genauso geschrieben wurden, repräsentierten das gleiche Objekt, während jede Liste ein separates Objekt war, das unabhängig von anderen Listen geändert werden konnte und von Vergleichsbetreibern von anderen Listen unterschieden werden konnte.

Da wurden weitere Datentypen in späteren Lisp -Dialekten eingeführt, und Programmierstile Das Konzept eines Atoms verlor die Bedeutung. Viele Dialekte behielten das Prädikat immer noch bei Atom zum Legacy -Kompatibilität, definieren es für jedes Objekt, das kein Nachteil ist.

Konzipiert und listet auf

Box-und-Zeiger Diagramm für die Liste (42 69 613)

Eine Lisp -Liste wird als implementiert als einzig verknüpfte Liste.[58] Jede Zelle dieser Liste wird a genannt Nachteile (im Schema, a Paar) und besteht aus zwei Zeiger, genannt Wagen und CDR. Diese entsprechen dem jeweils der data und next In dem Artikel diskutierte Felder verlinkte Liste.

Von den vielen Datenstrukturen, die aus Cons -Zellen aufgebaut werden können, wird eine der grundlegendsten als a genannt richtige Liste. Eine ordnungsgemäße Liste ist entweder die Special nil (leere Liste) Symbol oder Nachteile, in dem die car zeigt auf ein Datum (was eine weitere Nachteile sein kann, wie z. B. eine Liste) und die cdr zeigt auf eine andere richtige Liste.

Wenn ein bestimmter Nachteil als Kopf einer verknüpften Liste angesehen wird, weist ihr Auto auf das erste Element der Liste hin, und der CDR zeigt auf den Rest der Liste. Aus diesem Grund die car und cdr Funktionen werden auch genannt first und rest Bei Bezug auf Konsums, die Teil einer verknüpften Liste sind (und nicht beispielsweise eines Baumes).

Eine Lisp -Liste ist daher kein Atomobjekt, als Instanz einer Containerklasse in C ++ oder Java wäre. Eine Liste ist nichts weiter als ein Gesamtbetrag von verknüpften Konflikten. Eine Variable, die sich auf eine bestimmte Liste bezieht, ist einfach ein Zeiger auf die ersten Nachteile in der Liste. Durchqueren einer Liste können durch Cdring nach unten Die Liste; das heißt, aufeinanderfolgende CDRs zu nehmen, um jede Nachteile der Liste zu besuchen; oder indem Sie einige von mehreren verwenden Funktionen höherer Ordnung um eine Funktion über eine Liste zuzuordnen.

Da Konsums und Listen in LISP -Systemen so universell sind, ist es ein weit verbreitetes Missverständnis, dass sie die einzigen Datenstrukturen von LiSP sind. In der Tat haben alle bis auf die simpistischsten LISPs andere Datenstrukturen wie Vektoren (Vektoren (Arrays), Hash -Tische, Strukturen und so weiter.

S-Expressionen repräsentieren Listen

Klammern von S-Expressionen repräsentieren verknüpfte Listenstrukturen. Es gibt verschiedene Möglichkeiten, dieselbe Liste wie eine S-Expression darzustellen. Ein Nachteil kann geschrieben werden in Notation gepunktete Pair wie (a . b), wo a ist das Auto und b der cdr. Eine längere richtige Liste könnte geschrieben werden (a . (b . (c . (d . nil)))) in der Notation mit gepunktetem Pair. Dies wird herkömmlicherweise als abgekürzt (a b c d) in Notation auflisten. Eine unsachgemäße Liste[59] kann in einer Kombination der beiden geschrieben werden - als (a b c . d) Für die Liste der drei Konsums, deren letzter CDR ist d (d. h. die Liste (a . (b . (c . d))) in vollständiger Form).

Listenverarbeitungsverfahren

LISP bietet viele integrierte Verfahren für den Zugriff auf und steuern Listen. Listen können direkt mit dem erstellt werden list Verfahren, das eine beliebige Anzahl von Argumenten erfordert und die Liste dieser Argumente zurückgibt.

 (aufführen 1 2 'a 3)  ; Ausgabe: (1 2 a 3) 
 (aufführen 1 '(2 3) 4)  Ausgang: (1 (2 3) 4) 

Wegen der Art und Weise, wie Listen erstellt werden Nachteile Paare, das cons Vorgehensweise kann ein Element zur Vorderseite einer Liste hinzufügen. Notiere dass der cons Das Verfahren ist asymmetrisch in der Art und Weise, wie die Listenargumente behandelt werden, da die Listen konstruiert werden.

 (Nachteile 1 '(2 3))  Ausgang: (1 2 3) 
 (Nachteile '(1 2) '(3 4))  Ausgabe: (1 2) 3 4) 

Das append Die Prozedur findet zwei (oder mehr) Listen miteinander an. Da LISP -Listen verknüpfte Listen sind, hat das Anhängen von zwei Listen angemessen Asymptotische Zeitkomplexität

 (anhängen '(1 2) '(3 4))  Ausgang: (1 2 3 4) 
 (anhängen '(1 2 3) '() '(a) '(5 6))  Ausgang: (1 2 3 a 5 6) 

Gemeinsame Struktur

LISP -Listen, die einfache verknüpfte Listen sind, können Struktur miteinander teilen. Das heißt, zwei Listen können dasselbe haben Schwanz, oder endgültige Abfolge von Konsums. Zum Beispiel nach der Ausführung des folgenden gemeinsamen Lisp -Code:

(setf Foo (aufführen 'a 'b 'c)) (setf Bar (Nachteile 'x (CDR Foo))) 

die Listen foo und bar sind (a b c) und (x b c) beziehungsweise. Allerdings der Schwanz (b c) ist die gleiche Struktur in beiden Listen. Es ist keine Kopie; die cons -Zellen zeigen auf b und c sind an den gleichen Speicherorten für beide Listen.

Das Teilen von Struktur und nicht das Kopieren kann eine dramatische Leistungsverbesserung ergeben. Diese Technik kann jedoch auf unerwünschte Weise mit Funktionen interagieren, die Listen ändern, die ihnen als Argumente übergeben werden. Ändern einer Liste, z. B. durch das Ersetzen der c mit einer goose, wird den anderen beeinflussen:

 (setf (dritte Foo) 'Gans) 

Dies ändert sich foo zu (a b goose), aber dadurch ändert sich auch bar zu (x b goose) - Ein möglicherweise unerwartetes Ergebnis. Dies kann eine Quelle für Fehler sein, und Funktionen, die ihre Argumente ändern, werden dokumentiert als destruktiv Aus diesem Grund.

Liebhaber von Funktionelle Programmierung Vermeiden Sie destruktive Funktionen. Im Schema -Dialekt, der den funktionalen Stil begünstigt set-car! (lesen Autosalmer setzen), das das Auto eines Nachteils ersetzt. Im gemeinsamen Lisp -Dialekt sind zerstörerische Funktionen an der Tagesordnung; das Äquivalent von set-car! benannt rplaca für "Auto ersetzen". Diese Funktion ist jedoch selten zu sehen, da das gemeinsame Lisp eine spezielle Einrichtung umfasst. setf, um es einfacher zu machen, destruktive Funktionen zu definieren und zu verwenden. Ein häufiger Stil in gemeinsamem LISP ist es, beim Prototyping Code funktional (ohne destruktive Aufrufe) zu schreiben und dann zerstörerische Anrufe als Optimierung hinzuzufügen, wo es sicher ist.

Selbstbewertende Formen und Zitieren

LISP bewertet Ausdrücke, die vom Benutzer eingegeben werden. Symbole und Listen bewerten einen anderen (normalerweise, einfacheren) Ausdruck - zum Beispiel bewertet ein Symbol den Wert der Variablen -IT -Namen. (+ 2 3) bewertet 5. Die meisten anderen Formen bewerten sich jedoch: Wenn Sie eintreten 5 In Lisp, es kehrt zurück 5.

Jeder Ausdruck kann auch markiert werden, um zu verhindern, dass er bewertet wird (wie für Symbole und Listen erforderlich). Dies ist die Rolle der quote Spezialbetreiber oder Abkürzung ' (eine Anführungszeichen). Zum Beispiel normalerweise beim Eingeben des Symbols fooEs gibt den Wert der entsprechenden Variablen (oder eines Fehlers zurück, wenn keine solche Variable vorhanden ist). Um sich auf das wörtliche Symbol zu beziehen, geben Sie ein (quote foo) oder normalerweise, 'foo.

Sowohl das gemeinsame Lisp- als auch das Schema unterstützen auch die Rückquote Bediener (bezeichnet Quaquote im Schema), eingetragen mit dem ` Charakter (Gravis). Dies ist fast das gleiche wie das einfache Zitat, mit der Ausnahme, dass die Ausdrücke bewertet werden und ihre Werte in eine zitierte Liste mit dem Komma interpoliert werden , unquote und Komma-at ,@ spleißen Betreiber. Wenn die Variable snue hat den Wert (bar baz) dann `(foo ,snue) bewertet (foo (bar baz)), während `(foo ,@snue) bewertet (foo bar baz). Die Backquote wird am häufigsten zur Definition von Makroerweiterungen verwendet.[60][61]

Selbstbewertende Formen und zitierte Formen sind Lisps Äquivalent von Literalen. Es kann möglich sein, die Werte von (veränderlichen) Literalen im Programmcode zu ändern. Wenn beispielsweise eine Funktion ein zitiertes Formular zurückgibt und der Code, der die Funktion aufruft, das Formular ändert, kann dies das Verhalten der Funktion bei nachfolgenden Aufrufe verändern.

(Defun Sollten konstant ()  '(eines zwei drei)) (Lassen ((Sachen (Sollten konstant)))  (setf (dritte Sachen) 'bizarr))  ; Schlecht! (Sollten konstant)  ; kehrt zurück (ein zwei bizarr) 

Das Ändern einer zitierten Form wie dieser wird im Allgemeinen als schlechter Stil angesehen und durch ANSI Common Lisp als fehlerhaft definiert (was zu einem "undefinierten" Verhalten in kompilierten Dateien führt, da der Dateikompiler ähnliche Konstanten zusammenfassen kann, sie in schreibgeschütztes Speicher einfügen kann, Speicher etc.).

Die Formalisierung des Zitats von Lisp wurde von festgestellt Douglas Hofstadter (in Gödel, Escher, Bach) und andere als Beispiel für die philosophisch Idee von Selbstreferenz.

Umfang und Schließung

Die Lisp -Familie spaltet sich über die Verwendung von dynamisch oder statisch (a.k.a. lexikalisch) Umfang. Clojure, Common Lisp und Schema nutzen statische Scoping standardmäßig, während Newlisp, Picolisp und die eingebetteten Sprachen in EMACs und Autocad Verwenden Sie dynamisches Scoping. Seit Version 24.1 verwendet EMACs sowohl dynamische als auch lexikalische Scops.

Listenstruktur des Programmcodes; Ausbeutung durch Makros und Compiler

Eine grundlegende Unterscheidung zwischen Lisp und anderen Sprachen besteht darin, dass in Lisp die textuelle Darstellung eines Programms lediglich eine menschenlesbare Beschreibung der gleichen internen Datenstrukturen (verknüpfte Listen, Symbole, Anzahl, Zeichen usw.) ist das zugrunde liegende Lisp -System.

LISP verwendet dies, um ein sehr leistungsstarkes Makrosystem zu implementieren. Wie andere Makrosprachen wie die von der definierten Makrosprachen C Präprozessor (Der Makro -Präprozessor für die C, Ziel c und C ++ Programmiersprachen), ein Makro gibt Code zurück, der dann kompiliert werden kann. Im Gegensatz zu C -Präprozessor -Makros sind die Makros jedoch Lisp -Funktionen und können daher die volle Kraft von Lisp ausnutzen.

Da Lisp Code die gleiche Struktur wie Listen hat, können Makros mit einer der Listenverarbeitungsfunktionen in der Sprache erstellt werden. Kurz gesagt, alles, was Lisp für eine Datenstruktur tun kann, kann Lisp -Makros zum Code tun. Im Gegensatz dazu ist in den meisten anderen Sprachen die Ausgabe des Parsers rein für die Sprachimplementierung und kann vom Programmierer nicht manipuliert werden.

Diese Funktion erleichtert die Entwicklung effizient Sprachen in Sprachen. Beispielsweise kann das gemeinsame Lisp -Objektsystem mithilfe von Makros sauber als Sprachverlängerung implementiert werden. Dies bedeutet, dass wenn eine Anwendung einen anderen Vererbungsmechanismus benötigt, sie ein anderes Objektsystem verwenden kann. Dies steht in starkem Gegensatz zu den meisten anderen Sprachen; Zum Beispiel unterstützt Java keine mehrfache Vererbung und es gibt keinen vernünftigen Weg, es hinzuzufügen.

In simplen Lisp -Implementierungen ist diese Listenstruktur direkt interpretiert das Programm ausführen; Eine Funktion ist buchstäblich eine Listenstruktur, die vom Dolmetscher bei der Ausführung durchquert wird. Die meisten wesentlichen Lisp -Systeme umfassen jedoch auch ein Compiler. Der Compiler übersetzt die Listenstruktur in den Maschinencode oder in den Maschinencode oder Bytecode Für die Ausführung. Dieser Code kann so schnell ausgeführt wie der Code, der in herkömmlichen Sprachen wie C zusammengestellt wurde, wie C.

Makros erweitern sich vor dem Kompilierungsschritt und bieten daher einige interessante Optionen. Wenn ein Programm eine vorkundige Tabelle benötigt, kann ein Makro die Tabelle zum Kompilierzeit erstellen, sodass der Compiler nur die Tabelle ausgeben muss und keinen Code zum Erstellen der Tabelle zum Laufzeit erstellt hat. Einige LISP -Implementierungen haben sogar einen Mechanismus, eval-whenDies ermöglicht es, Code während der Kompilierungszeit vorhanden zu sein (wenn ein Makro benötigt wird), aber nicht im emittierten Modul vorhanden.[62]

Evaluierung und die Lesung -E -E -Drucken -Schleife

Lisp -Sprachen werden oft mit einem interaktiven verwendet Befehlszeile, was mit einem kombiniert werden kann integrierte Entwicklungsumgebung (Ide). Der Benutzer typisch in Ausdrücken in der Befehlszeile oder leitet die IDE an das LISP -System übertragen. Lispeln liest die eingegebenen Ausdrücke, bewertet sie und Drucke das Ergebnis. Aus diesem Grund wird die Lisp -Befehlszeile a genannt Read -E -druck -Schleife (Wiederholung).

Der grundlegende Betrieb der Wiederholung ist wie folgt. Dies ist eine simple Beschreibung, die viele Elemente eines echten Lisps weglässt, wie z. B. Zitieren und Makros.

Das read Die Funktion akzeptiert textliche S-Expressionen als Eingabe und analysiert sie in eine interne Datenstruktur. Zum Beispiel, wenn Sie den Text eingeben (+ 1 2) Auf der Eingabeaufforderung, read Übersetzt dies in eine verknüpfte Liste mit drei Elementen: dem Symbol +, die Nummer 1 und die Nummer 2. Es kommt so vor, dass diese Liste auch ein gültiges Stück Lisp -Code ist. Das heißt, es kann bewertet werden. Dies liegt daran, dass das Auto der Listen eine Funktion nennt - die Hinzufügung.

Beachten Sie, dass a foo wird als einzelnes Symbol gelesen. 123 wird als Nummer einhundertundzwanzig drei gelesen. "123" wird als Zeichenfolge "123" gelesen.

Das eval Die Funktion bewertet die Daten und gibt dadurch null oder mehr LISP -Daten zurück. Die Bewertung muss keine Interpretation bedeuten; Einige Lisp -Systeme kompilieren jeden Ausdruck mit dem nativen Maschinencode. Es ist jedoch einfach, die Bewertung als Interpretation zu beschreiben: eine Liste zu bewerten, deren Auto eine Funktion nennt. eval Bewertet zuerst jedes der in seinem CDR angegebenen Argumente und wendet dann die Funktion auf die Argumente an. In diesem Fall ist die Funktion zusätzlich und wendet sie auf die Argumentliste an (1 2) ergibt die Antwort 3. Dies ist das Ergebnis der Bewertung.

Das Symbol foo bewertet den Wert des Symbols foo. Daten wie die Zeichenfolge "123" bewertet die gleiche Zeichenfolge. Die Liste (quote (1 2 3)) bewertet die Liste (1 2 3).

Es ist die Aufgabe der print Funktion zur Darstellung der Ausgabe für den Benutzer. Für ein einfaches Ergebnis wie z. 3 Dies ist trivial. Ein Ausdruck, der auf ein Stück Listenstruktur bewertet wurde, würde dies erfordern print Durchqueren Sie die Liste und drucken Sie sie als S-Expression aus.

Um eine Lisp-Repl zu implementieren, ist es nur erforderlich, diese drei Funktionen und eine Infinite-Loop-Funktion zu implementieren. (Natürlich die Implementierung von eval wird komplex sein, da es auch alle speziellen Betreiber wie implementieren muss if oder lambda.) Dies erledigte eine grundlegende Reply eine Codezeile: (loop (print (eval (read)))).

Die LISP -Reply bietet normalerweise auch Eingabemittel, einen Eingangsgeschichte, Fehlerbehandlung und eine Schnittstelle zum Debugger.

Lisp wird normalerweise bewertet eifrig. Im Common LispArgumente werden in bewertet in Anwendungsreihenfolge ('links in der innersten'), während in Planen Die Reihenfolge der Argumente ist undefiniert und lässt Raum für eine Optimierung durch einen Compiler.

Kontrollstrukturen

LISP hatte ursprünglich nur sehr wenige Kontrollstrukturen, aber während der Entwicklung der Sprache wurden viele weitere hinzugefügt. (LISPs ursprünglicher Bedingerbetreiber, cond, ist der Vorläufer später if-then-else Strukturen.)

Programmierer im Schema -Dialekt drücken häufig Schleifen mit Verwendung aus Schwanzrekursion. Die Gemeinsamkeit des Schemas in der akademischen Informatik hat einige Studenten zu der Annahme veranlasst, dass die Schwanzrekursion die einzige oder häufigste Möglichkeit ist, Iterationen in Lisp zu schreiben, aber dies ist falsch. Alle oft gesehenen Lisp-Dialekte haben Iterationskonstrukte im Bereich im Rahmen des Schemas do Schleife zu Common LispKomplex loop Ausdrücke. Darüber hinaus ist das Schlüsselproblem, das dies eher zu einem objektiven als zu subjektiven Angelegenheit macht SchwanzaufrufeUnd daher ist der Grund, warum die Verwendung der Schwanzrekursion im Allgemeinen für das Schema gefördert wird, dass die Praxis ausdrücklich durch die Sprachdefinition unterstützt wird. Im Gegensatz dazu erfordert ANSI Common Lisp nicht[63] Die Optimierung wurde üblicherweise als Eliminierung des Schwanzaufrufs bezeichnet. Die Tatsache, dass der schwanzrekursive Stil als lässiger Ersatz für die Verwendung von traditionelleren Wiederholung Konstrukte (wie z. do, dolist oder loop) ist entmutigt[64] In gemeinsamer LISP ist nicht nur eine Frage der stilistischen Präferenz, sondern möglicherweise auch der Effizienz (da ein offensichtlicher Schwanzaufruf in gemeinsamem Lisp möglicherweise nicht als einfacher kompiliert wird springen) und Programmkorrektheit (da die Schwanzreursion die Stapelverwendung in gemeinsamen Lispeln erhöhen kann, riskiert Paketüberfluss).

Einige Lisp -Kontrollstrukturen sind Spezialbetreiber, entspricht den syntaktischen Schlüsselwörtern anderer Sprachen. Ausdrücke, die diese Operatoren verwenden, haben das gleiche Oberflächenaussehen wie Funktionsaufrufe, unterscheiden sich jedoch darin, dass die Argumente nicht unbedingt bewertet werden - oder im Fall einer Iterationxpression mehr als einmal bewertet werden können.

Im Gegensatz zu den meisten anderen wichtigen Programmiersprachen ermöglicht LISP die Implementierung von Kontrollstrukturen mithilfe der Sprache. Mehrere Kontrollstrukturen werden als Lisp-Makros implementiert und können sogar von dem Programmierer, der wissen, wie sie funktionieren, makroexpandiert werden können.

Sowohl das gemeinsame LISP als auch das Schema haben Operatoren für den nicht-lokalen Kontrollfluss. Die Unterschiede in diesen Operatoren sind einige der tiefsten Unterschiede zwischen den beiden Dialekten. Schema unterstützt wieder eingetreten Kontinuationen Verwendung der call/cc Prozedur, mit der ein Programm einen bestimmten Ort in der Ausführung speichern (und später wiederherstellen) kann. Common Lisp unterstützt keine wiedereintretenden Kontinuationen, unterstützt jedoch verschiedene Wege des Umgangs mit Fluchtkontinuationen.

Oft kann der gleiche Algorithmus entweder in einem imperativen oder in einem funktionalen Stil in LISP ausgedrückt werden. Wie oben erwähnt, neigt das Schema dazu, den funktionalen Stil zu bevorzugen, wobei die Schwanzrekursion und die Fortschritte verwendet werden, um den Kontrollfluss auszudrücken. Der imperative Stil ist jedoch immer noch durchaus möglich. Der Stil, der von vielen gängigen LISP-Programmierern bevorzugt wird, scheint den Programmierern, die für strukturierte Sprachen wie C verwendet werden, besser bekannt zu Haskell.

Aufgrund des frühen Erbes von Lisp in der Listenverarbeitung verfügt es über eine Vielzahl von Funktionen höherer Ordnung, die sich auf die Iteration über Sequenzen beziehen. In vielen Fällen, in denen eine explizite Schleife in anderen Sprachen benötigt wird (wie a for Schleife in C) In Lisp kann die gleiche Aufgabe mit einer Funktion höherer Ordnung erfüllt werden. (Gleiches gilt für viele funktionale Programmiersprachen.)

Ein gutes Beispiel ist eine Funktion, die im Schema genannt wird map und in einem gemeinsamen Lisp wird genannt mapcar. Bei einer Funktion und einer oder mehreren Listen, mapcar Anwendet die Funktion nacheinander die Elemente der Listen in der Reihenfolge und sammelt die Ergebnisse in einer neuen Liste:

 (MAPCAR #'+ '(1 2 3 4 5) '(10 20 30 40 50)) 

Dies gilt das + Funktion zu jedem entsprechenden Listenelementpaar und ergibt das Ergebnis (11 22 33 44 55).

Beispiele

Hier sind Beispiele für gemeinsames Lisp -Code.

Das Basis "Hallo Welt!" Programm:

(drucken "Hallo Welt!") 

Lisp -Syntax eignet sich natürlich für Rekursion. Mathematische Probleme wie die Aufzählung rekursiv definierter Sätze sind in dieser Notation einfach ausdrücken. Zum Beispiel, um die Zahl zu bewerten Fakultät:

(Defun Fakultät (n)  (wenn (Nulle n) 1  (* n (Fakultät (1- n))))) 

Eine alternative Implementierung benötigt weniger Stapelraum als die vorherige Version, wenn das zugrunde liegende Lisp -System optimiert Schwanzrekursion:

(Defun Fakultät (n &Optional (Acc 1))  (wenn (Nulle n) Acc  (Fakultät (1- n) (* Acc n)))) 

Vergleichen Sie die obigen Beispiele mit einer iterativen Version, die verwendet Common Lisp's loop Makro:

(Defun Fakultät (n)  (Schleife zum i aus 1 zu n  zum FAC = 1 dann (* FAC i)  endlich (Rückkehr FAC))) 

Die folgende Funktion kehrt eine Liste um. (Lisps integriert umkehren Funktion macht dasselbe.)

(Defun -umkehren (aufführen)  (Lassen ((Rückgabewert))  (Dolist (e aufführen) (drücken e Rückgabewert))  Rückgabewert)) 

Objektsysteme

Verschiedene Objektsysteme und Modelle wurden neben, neben LISP, einschließlich:

  • Das Gemeinsames Lisp -Objektsystem, CLOS, ist ein wesentlicher Bestandteil von ANSI Common Lisp. CLOS stieg von neuen Geschmacksrichtungen und Commonloops ab. ANSI Common Lisp war die erste standardisierte objektorientierte Programmiersprache (1994, ANSI X3J13).
  • Objektlisp[65] oder Objekt Lisp, benutzt von Lisp -Maschinen eingebaut und frühe Versionen von Macintosh Common Lisp
  • Schleifen (LiSP-Objekt-orientiertes Programmiersystem) und das spätere Commonloops
  • Flavors, gebaut bei MITund sein Nachkomme neue Aromen (entwickelt von Symbolik).
  • KR (kurz für Wissensrepräsentation), a Einschränkungen-Basierte Objektsystem, die entwickelt wurde, um das Schreiben von Granat zu unterstützen, einer GUI -Bibliothek für Common Lisp.
  • Wissenstechnikumgebung (KEE) verwendeten ein Objektsystem namens Einheiten und integrierte es mit einem Inferenzmotor[66] und ein Wahrheitswartung System (Geldautomaten).

Betriebssysteme

Mehrere Betriebssysteme, einschließlich Sprachbasierte Systeme, basieren auf LISP (verwenden Sie Lisp -Funktionen, Konventionen, Methoden, Datenstrukturen usw.) oder sind in LiSP geschrieben,[67] einschließlich:

Gattungen, in Open Gattungen umbenannt,[68] durch Symbolik; Medley, geschrieben in Interisp, ursprünglich eine Familie grafischer Betriebssysteme, die auf dem Laufenden waren Xeroxspäter Stern Arbeitsstationen;[69][70] Mezzano;[71] Interim;[72][73] Chrysalisp,[74] von Entwicklern von Tao Systems 'Taos.[75]

Siehe auch

Verweise

  1. ^ "Einführung". Das Julia -Handbuch. Lesen Sie die Dokumente. Archiviert von das Original am 2016-04-08. Abgerufen 2016-12-10.
  2. ^ "Wolfram Language Q & A" ". Wolfram -Forschung. Abgerufen 2016-12-10.
  3. ^ Edwin D. Reilly (2003). Meilensteine ​​in Informatik und Informationstechnologie. Greenwood Publishing Group. S. 156–157. ISBN 978-1-57356-521-9.
  4. ^ "SICP: Vorwort". Archiviert von das Original Am 2001-07-27. Lisp ist ein Überlebender, der seit ungefähr einem Vierteljahrhundert in Gebrauch ist. Unter den aktiven Programmiersprachen hat nur Forran ein längeres Leben gehabt.
  5. ^ "Schlussfolgerungen". Archiviert von das Original Am 2014-04-03. Abgerufen 2014-06-04.
  6. ^ Steele, Guy Lewis; Sussman, Gerald Jay (Mai 1978). "Die Kunst des Dolmetschers oder der Modularitätskomplex (Teile Null, eins und zwei), Teil Null, S. 4". MIT -Bibliotheken. HDL:1721.1/6094. Abgerufen 2020-08-01.
  7. ^ "Die Top -Programmiersprachen in künstlicher Intelligenz". Künstliche Intelligenz. Apro. 24. Juni 2020. Archiviert vom Original am 2020-10-30. Abgerufen 2021-02-15.
  8. ^ Paul Graham. "Rache der Nerds". Abgerufen 2013-03-14.
  9. ^ Chisnall, David (2011-01-12). Einflussreiche Programmiersprachen, Teil 4: Lisp.
  10. ^ Jones, Robin; Maynard, Clive; Stewart, Ian (6. Dezember 2012). Die Kunst der Lisp -Programmierung. Springer Science & Business Media. p. 2. ISBN 9781447117193.
  11. ^ McCarthy, John. "Rekursive Funktionen symbolischer Ausdrücke und ihre Berechnung nach Maschine, Teil I". Archiviert von das Original Am 2013-10-04. Abgerufen 2006-10-13.
  12. ^ Smith, David Canfield. MLISP -Benutzerhandbuch (PDF). Abgerufen 2006-10-13.
  13. ^ McCarthy, John (12. Februar 1979). "Geschichte des Lisp: Labor für künstliche Intelligenz" (PDF).
  14. ^ Stoyan, Herbert (1984-08-06). Frühe Lisp -Geschichte (1956–1959). LFP '84: Verfahren des ACM -Symposiums von 1984 über LISP und funktionelle Programmierung. Verband für Rechenmaschinen. p. 307. doi:10.1145/800055.802047. Archiviert von das Original am 2005-04-05.
  15. ^ McCarthy, John. "Lisp -Vorgeschichte - Sommer 1956 bis Sommer 1958". Abgerufen 2010-03-14.
  16. ^ Hart, Tim; Levin, Mike. "KI-Memo 39-The New Compiler" (PDF). Archiviert von das Original (PDF) am 2020-12-13. Abgerufen 2019-03-18.
  17. ^ McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I. (1985) [1962]. LISP 1.5 -Programmierhandbuch (PDF). 15. Druck (2. Aufl.). p. Vorwort.
  18. ^ Die 36-Bit-Wortgröße der PDP-6/PDP-10 wurde von der Nützlichkeit von zwei Lisp-18-Bit-Zeigern in einem einzigen Wort beeinflusst. Peter J. Hurley (18. Oktober 1990). "Die Geschichte der Oberteile oder des Lebens im schnellen ACS". Newsgroup:Alt.folklore.computer. Usenet: [email protected]. Das PDP-6-Projekt begann Anfang 1963 als 24-Bit-Maschine. Es wuchs auf 36 Bit für Lisp, ein Designziel.
  19. ^ Steele, Guy L.; Gabriel, Richard P. (Januar 1996), Bergin, Thomas J.; Gibson, Richard G. (Hrsg.), "Die Entwicklung von Lisp" ", Geschichte der Programmiersprachen --- ii, New York, NY, USA: ACM, S. 233–330, doi:10.1145/234286.1057818, ISBN 978-0-201-89502-5, abgerufen 2022-07-25
  20. ^ Common Lisp: (Defun f (x) x)
    Planen: (Definieren Sie F (Lambda (x) x)) oder (definieren (f x) x)
  21. ^ McCarthy, J.; Brayton, R.; Edwards, D.; Fox, P.; Hodes, L.; Luckham, D.; Maling, K.; Park, D.; Russell, S. (März 1960). "LISP I Programmierer Handbuch" (PDF). Boston, Massachusetts: Künstliche Intelligenzgruppe, M.I.T. Berechnungszentrum und Forschungslabor. Archiviert von das Original (PDF) Am 2010-07-17. {{}}: Journal zitieren erfordert |journal= (Hilfe) Zugriff am 11. Mai 2010.
  22. ^ McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I. (1985) [1962]. LISP 1.5 -Programmierhandbuch (PDF) (2. Aufl.). MIT Press. ISBN 0-262-13011-4.
  23. ^ Quam, Lynn H.; Differ, Whitfield. Stanford Lisp 1.6 Handbuch (PDF).
  24. ^ "MacLisp -Referenzhandbuch". 3. März 1979. archiviert von das Original Am 2007-12-14.
  25. ^ Teitelman, Warren (1974). Interisp -Referenzhandbuch (PDF). Archiviert von das Original (PDF) am 2006-06-02. Abgerufen 2006-08-19.
  26. ^ Outils de Generation D’ Interfaces: Etat de l’Art ET -Klassifizierung von H. el Mrabet
  27. ^ Gerald Jay Sussman & Guy Lewis Steele Jr. (Dezember 1975). "Schema: Ein Dolmetscher für erweiterte Lambda -Kalkül" (PDF). AI -Memos. MIT AI Lab. AIM-349. Abgerufen 23. Dezember 2021.
  28. ^ Steele, Guy L., Jr. (1990). "Zweck". Gemeinsam lispeln die Sprache (2. Aufl.). ISBN 0-13-152414-3.
  29. ^ Kantrowitz, Mark; Margolin, Barry (20. Februar 1996). "Geschichte: Woher kam Lisp?". FAQ: Lisp häufig gestellte Fragen 2/7.
  30. ^ "ISO/IEC 13816: 1997". ISO.org. 2007-10-01. Abgerufen 2013-11-15.
  31. ^ "ISO/IEC 13816: 2007". ISO.org. 2013-10-30. Abgerufen 2013-11-15.
  32. ^ "X3J13 Charter".
  33. ^ "Der Weg zur Lisp -Umfrage". Archiviert von das Original Am 2006-10-04. Abgerufen 2006-10-13.
  34. ^ "Trends für die Zukunft". Faqs.org. Archiviert von das Original Am 2013-06-03. Abgerufen 2013-11-15.
  35. ^ Weinreb, Daniel. "Common Lisp -Implementierungen: Eine Umfrage". Archiviert von das Original Am 2012-04-21. Abgerufen 4. April 2012.
  36. ^ "Lisp50@oopsla". Lisp50.org. Abgerufen 2013-11-15.
  37. ^ Dokumente: Standards: R5Rs. Schemers.org (2012-01-11). Abgerufen am 2013-07-17.
  38. ^ "Warum MIT jetzt Python anstelle von Schema für sein Bachelor -CS -Programm verwendet". cemerick.com. 24. März 2009. archiviert von das Original am 17. September 2010. Abgerufen 10. November, 2013.
  39. ^ Broder, Evan (8. Januar 2008). "Das Ende einer Ära". Mitadmissions.org. Abgerufen 10. November, 2013.
  40. ^ "MIT EECS -Bachelor -Programme". www.eecs.mit.edu. MIT Elektrotechnik und Informatik. Abgerufen 31. Dezember 2018.
  41. ^ "MITX Einführende Python -Kurs erreicht 1,2 Millionen Einschreibungen". Mit EECs. MIT Elektrotechnik und Informatik. Abgerufen 31. Dezember 2018.
  42. ^ Kapitel 1.1.2, Geschichte, ANSI CL Standard
  43. ^ [1] Clasp ist eine gemeinsame LiSP -Implementierung, die mit C ++ unterwegs ist und LLVM für verwendet Just-in-Time-Zusammenstellung (JIT) zum nativen Code.
  44. ^ [2] "Armed Bear Common Lisp (ABCL) ist eine vollständige Implementierung der gemeinsamen Lisp -Sprache mit einem Dolmetscher und einem Compiler, der in der JVM ausgeführt wird."
  45. ^ [3] Archiviert 2018-06-22 bei der Wayback -Maschine Common Lisp -Implementierungen: Eine Umfrage
  46. ^ [4] Vergleich von aktiv entwickelten gemeinsamen LISP -Implementierungen
  47. ^ Ein ausführlicher Blick auf Clojure-Sammlungen, Abgerufen 2012-06-24
  48. ^ "Clojure rational". Abgerufen 27. August 2019. Clojure ist eine Lisp
  49. ^ Skript-Fu in GIMP 2.4, Abgerufen 2009-10-29
  50. ^ librep in Sawfish Wikia, Abruft 2009-10-29
  51. ^ "IEEE -Schema". IEEE 1178-1990 - IEEE -Standard für die Programmiersprache für Schema. Abgerufen 27. August 2019.
  52. ^ "Lisp -Vorgeschichte - Sommer 1956 bis Sommer 1958". Ich habe bedingte Ausdrücke im Zusammenhang mit einer Reihe von Schach -Rechtsbewegungsroutinen erfunden, die ich für den IBM 704 bei M.I.T. In den Jahren 1957 bis 1958 wurde ein Papier, das bedingte Ausdrücke definiert und ihre Verwendung in Algol vorschlug, zur Kommunikation des ACM gesendet, wurde jedoch willkürlich zu einem Brief an den Herausgeber herabgestuft, weil es sehr kurz war.
  53. ^ "Bedeutung von 'objektorientiertes Programmieren' nach Dr. Alan Kay". 2003-07-23. Ich habe damals die Monster Lisp -Idee einer materiellen Metallangruppe nicht verstanden, aber mit Ideen über erweiterbare Sprachen englisch zusammengekommen ... die zweite Phase davon bestand darin Mächtige und spät gebundene Unterstrukturen ... oop für mich bedeutet nur Messaging, lokale Aufbewahrung und Schutz und Versteck von Staatsprozess und extrem verspätete Bindung aller Dinge. Es kann in SmallTalk und in Lisp erledigt werden. Es gibt möglicherweise andere Systeme, in denen dies möglich ist, aber ich bin mir dessen nicht bewusst.
  54. ^ Lieberman, Henry; Hewitt, Carl (Juni 1983), "Ein Echtzeit-Müllsammler basiert auf den Lebensdauern von Objekten", Kommunikation der ACM, 26 (6): 419–429, Citeseerx 10.1.1.4.8633, doi:10.1145/358141.358147, HDL:1721.1/6335, S2CID 14161480
  55. ^ Edsger W. Dijkstra (1972), Der bescheidene Programmierer (EWD 340) (ACM Turing Award Lecture).
  56. ^ "Ein Blick auf Clojure und die Lisp -Wiederbelebung".
  57. ^ "Die Jargon -Datei - Lisp". Abgerufen 2006-10-13.
  58. ^ Sebesta, Robert W. (2012). ""2.4 funktionale Programmierung: Lisp"; "6.9 Listentypen"; "15.4 Die erste funktionale Programmiersprache: Lisp"". Konzepte von Programmiersprachen (drucken) (10. Aufl.). Boston, MA, USA: Addison-Wesley. S. 47–52, 281–284, 677–680. ISBN 978-0-13-139531-2.
  59. ^ NB: Eine sogenannte "gepunktete Liste" ist nur eine Art von "unsachgemäßer Liste". Die andere Art ist die "zirkuläre Liste", in der die Cons -Zellen eine Schleife bilden. Typischerweise wird dies unter Verwendung von #N = (...) dargestellt, um die Zielkonsumzelle mit mehreren Referenzen darzustellen, und #n #wird verwendet, um auf diese Nachteile zu verweisen. Zum Beispiel wird (#1 = (a b).#1##) normalerweise als ((a b) a b) (ohne aktivierende Strukturdruck) gedruckt, macht jedoch die Wiederverwendung der CONS -Zelle klar. #1 = (a. #1 #) kann normalerweise nicht so gedruckt werden, wie es kreisförmig ist, obwohl (a ...) manchmal angezeigt wird, ist der CDR der durch #1 = selbst definierten CONS -Zelle selbst.
  60. ^ "CSE 341: Schema: Zitat, Quasiquote und Metaprogrammierung". CS.Washington.edu. 1999-02-22. Abgerufen 2013-11-15.
  61. ^ Quaquotation in Lisp Archiviert 2013-06-03 bei der Wayback -MaschineAlan Bawden
  62. ^ Zeit der Bewertung - gemeinsame Lisp -Erweiterungen. Gnu.org. Abgerufen am 2013-07-17.
  63. ^ 3.2.2.3 Semantische Einschränkungen in Common Lisp hyperspec
  64. ^ 4.3. Kontrollabstraktion (Rekursion vs. Iteration) in Tutorial zum guten Lisp -Programmierstil durch Kent Pitman und Peter Norvig, August 1993.
  65. ^ S. 17 von Bobrow 1986
  66. ^ Veitch, S. 108, 1988
  67. ^ Provenen, Liam (29. März 2022). "Die wilde Welt der Nicht-C-Betriebssysteme". Das Register. Abgerufen 2022-02-02.
  68. ^ "Symbolics Open Gattungen 2.0". GitHub Internetarchiv. 7. Januar 2020. Abgerufen 2022-02-02.
  69. ^ "Interisp.org Project". Interisp.org. 15. März 2022. Abgerufen 2022-02-02.
  70. ^ "Interisp Medley". GitHub. März 2022. Abgerufen 2022-02-02.
  71. ^ Froggey (1. August 2021). "Mezzano". GitHub. Abgerufen 2022-02-02.
  72. ^ Hartmann, Lukas F. (10. September 2015). "Interim". Interim-Os. Abgerufen 2022-02-02.
  73. ^ Hartmann, Lukas F. (11. Juni 2021). "Interim". GitHub. Abgerufen 2022-02-02.
  74. ^ Hinsley, Chris (23. Februar 2022). "Chrysalisp". GitHub. Abgerufen 2022-02-02.
  75. ^ Smith, Tony (21. August 2013). "UK Micro Pioneer Chris Shelton: Der Geist hinter dem Nascom 1". Das Register. Abgerufen 2022-02-02.

Weitere Lektüre

Externe Links

Geschichte
Assoziationen und Besprechungen
Bücher und Tutorials
Interviews
Ressourcen