
Common Lisp ist eine in erster Linie funktionale Programmiersprache, die aspektorientierte und mit CLOS, dem Common Lisp Object System, auch objektorientierte Programmierung ermöglicht.
Lisp, „LISt Processing“, ist eine 1958 erstmals erschienene Familie von Programmiersprachen und nach Fortran die zweitälteste höhere Programmiersprache. Neben Common Lisp sind Racket, Scheme und Clojure weitere bekannte Vertreter dieser Sprachfamilie. Lisp wurde ursprünglich vom US-amerikanischen Informatiker und Forscher John McCarthy entworfen, zunächst als mathematische Notation verwendet und war dabei stark vom Lambda-Kalkül geprägt. Später hat sich Lisp zu einer beliebten Sprache für künstliche Intelligenz entwickelt.
1966 ist im Rahmen von Project MAC (Mathematics and Computation) beim MIT (Massachusetts Institute of Technology) der Dialekt Maclisp entstanden. Auf Basis von Maclisp folgten weitere zueinander allerdings inkompatible Lisp-Dialekte, woraufhin ab 1981 an einer gemeinsamen Spezifikation eines Nachfolgers gearbeitet wurde. Dieser Nachfolger war das 1984 veröffentlichte Common Lisp, welches später ANSI-standardisiert wurde und sich seit der Spezifikation ANSI/X3.226-1994 aus dem Jahr 1994 nicht mehr weiter verändert hat.
Da Common Lisp vorrangig eine Spezifikation ist, gibt es zahlreiche quelloffene sowie auch proprietäre Implementierungen. Als eine der verbreiteteren gilt SBCL (Steel Bank Common Lisp).
Alleinstellungsmerkmale
Common Lisp (und Lisp im Allgemeinen) ist eine homoikonische Sprache. Jede Anweisung und jedes Lisp-Programm wird als sogenannte S-Expression abgebildet, eine Art verschachtelte Liste bzw. Baumstruktur. Eine Differenzierung zwischen Code und Daten findet dabei nicht statt. Dadurch kann auf sehr natürliche Weise aus Lisp heraus Programmcode erzeugt werden, was Lisp wiederum für Metaprogrammierung prädestiniert.
Common Lisp bietet eine sehr schlanke Syntax, die vorwiegend aus runden Klammern besteht. Kontrollflusselemente wie Schleifen und Verzweigungen werden durch S-Expressions abgebildet, statt wie in vielen Sprachen durch Schlüsselwörter. Durch den Einsatz von Macros können beliebige neue Kontrollstrukturen und syntaktischer Zucker als S-Expressions realisiert werden.
Einsatzbereiche
Lisp ist auf dem Arbeitsmarkt eine eher exotische Sprache. Eine bekannte Online-Stellensuche findet zum Stichwort Lisp 40 Stellen in Deutschland, dem gegenüber ergibt das Stichwort Java fast 24000 Treffer.
Grammarly ist einer der bekannteren großen Dienste, die Common Lisp ausgiebig in ihrem Backend in Produktion einsetzen. Ein Blogbeitrag dazu ist am Ende dieses Artikels verlinkt. Der Allegro NFS Server (Network File System Server) ist in Common Lisp geschrieben und unter anderem bei Boeing im Einsatz.
Das Unternehmen ITA Software, 2010 von Google akquiriert, war bekannt dafür seine Software vorwiegend in Common Lisp zu schreiben. Ein weiteres solches Unternehmen ist Siscog, welches auf Software für Verkehrssysteme spezialisiert ist, dafür überwiegend Common Lisp einsetzt und Eisenbahnunternehmen zahlreicher Nationen als Kunden hat, darunter die London Underground.
Bemerkenswert ist die Sprache Game Oriented Assembly Lisp (GOAL), die in Common Lisp geschrieben ist und bei dem Unternehmen Naughty Dog unter anderem für die Videospielreihe Jak and Daxter ausgiebig zum Einsatz kam. Seit dem Aufkauf des Unternehmens durch Sony beschränkt sich der Einsatz von GOAL auf Scripting, etwa im Videospiel The Last of Us.
Daneben gibt es zahlreiche in Common Lisp geschriebene Endanwenderprogramme. Am Ende des Blogbeitrags ist eine Auflistung solcher Programme aus dem common lisp wiki verlinkt. Ich persönlich kenne leider keines von denen.
Pros
Common Lisp ist eine sehr schnelle Sprache und kann annähernd die Geschwindigkeit von C erreichen. Was sehr beeindruckend ist, wenn man bedenkt, dass Common Lisp dynamisch typisiert ist und über eine automatische Speicherbereinigung verfügt.
Die Syntax von Common Lisp, die im Wesentlichen aus S-Expressions besteht, ist sehr rudimentär, leicht zu erlernen und gleichzeitig extrem mächtig. Macros ermöglichen Metaprogrammierung. Der Einstieg darin ist sehr einfach. Aus meiner Sicht signifikant einfacher, als beispielsweise der Einstieg in die Annotation Processing API zur Metaprogrammierung in Java.
Common Lisp ermöglicht eine sehr flexible Parametrisierung, dazu gehören Optional Arguments, Variable Arguments, Named Arguments und Default Arguments.
Das Common Lisp Object System ermöglicht objektorientierte Programmierung inklusive Mehrfachvererbung.
Ein kleiner aber feiner Bonus ist die Verwendung des Bindestrichs zur Trennung von Wörtern innerhalb von Bezeichnern anstelle von Unterstrichen oder Großkleinschreibung. Zwar wird dieser Stil von der Sprache nicht forciert, jedoch überhaupt erst ermöglicht, denn in vielen Sprachen ist der Bindestrich kein gültiges Zeichen in Bezeichnern. Der Vorteil vom sogenannten Kebab Case gegenüber Camel Case und Snake Case liegt in der Lesbarkeit und darin, dass nicht die Shift-Taste bzw. zwei Tasten zur gleichen Zeit gedrückt werden müssen, wie es für Großbuchstaben und Unterstriche in allen gängen Tastaturlayouts notwendig ist.
Ich persönlich empfinde die Syntax von Common Lisp im Allgemeinen als sehr angenehm und produktiv. Statt von links nach rechts wie in C und ähnlichen Sprachen, denke ich beim Schreiben von Lisp-Code mehr von innen nach außen, statt in Schleifen mit vielen lokalen Variablen mehr in Rekursion. Ich finde es beim Schreiben komplexer Ausdrücke einfacher, mich auf die aktuelle S-Expression zu konzentrieren, als in anderen Sprachen auf „eine Zeile Code“. Statt in Methodensignaturen, Typen, Rückgabewerten, Listen, Typisierung etc. zu denken und dabei eine Vielzahl an Schlüsselwörtern und Sonderzeichen mit syntaktischer Bedeutung im Kopf zu haben, beschränke ich mich auf die Einfachheit von S-Expressions und wenigen syntaktischen Ergänzungen wie Zeichenketten und Symbolen.
Vergleicht man die Syntax der Sprache etwa mit Java, so ist es bemerkenswert, wie sich fast alles nur mit runden Klammern, Leerzeichen, Anführungszeichen, Et-Zeichen, Doppelpunkten und Bezeichnern ausdrücken lässt, während man in Java mit runden, eckigen, spitzen und geschweiften Klammern, Punkten, Doppelpunkten Semikolons, At-Zeichen, diversen Operatoren und einer zweistelligen Anzahl an Schlüsselwörtern jongliert.
Cons
Die großen Nachteile von Common Lisp sind die geringe Verbreitung und damit einhergehend das kleine Ökosystem. Beispielsweise gibt es keine Funktion replaceAll
in der Standardbibliothek von Common Lisp, mit der man in einem String alle Treffer für einen Substring durch einen anderen ersetzen kann.
Weiterhin sei erwähnt, dass die Syntax von (Common) Lisp sicherlich Geschmackssache ist und sich nicht alle Entwickler damit anfreunden werden. Ich würde allerdings auch behaupten, dass dies in vielen Fällen der langjährigen Gewöhnung an andere Sprachen geschuldet ist und (Common) Lisp objektiv nicht schlechter lesbar ist, als z.B. Go oder Python.
Datenblatt
Name | Common Lisp |
Webseite | https://common-lisp.net/ |
Erscheinungsjahr | 1984 |
Aktuellste Version (Stand 2. Januar 2022) | ANSI/X3.226-1994 |
Typisierung | dynamisch |
Paradigmen | imperativ prozedural objektorientiert funktional aspektorientiert |
Pros | Cons |
---|---|
sehr schnell | geringe Verbreitung |
sehr mächtig | eher schlechte Aussichten auf dem Arbeitsmarkt |
sehr flexibel | kleines Ökosystem |
sehr simple Syntax | Syntax spricht nicht alle an |
funktional geprägt, aber trotzdem prozedural/objektorientiert einsetzbar |
virtuallet
virtuallet ist ein kleines Programm von mir, welches ich in diversen Programmiersprachen implementiert habe. Hier geht es direkt zum Lisp-Code von virtuallet auf GitLab. Hier gibt es weitere Infos zu virtuallet.
- Webseite von SBCL (Steel Bank Common Lisp) - Liste von Common Lisp Programmen im CLiki - Blogbeitrag zum Einsatz von Common Lisp in Produktion