Lisp, forkortelse for "LISt Processing," er en familie af programmeringssprog, der deler en karakteristisk syntaks baseret på parenteser, primært centreret omkring manipulation af symboler og lister. Det er et af de ældste højniveau programmeringssprog, oprindeligt opfundet i slutningen af 1950'erne, og det har udviklet sig betydeligt gennem årtierne. Lisp er især kendt for sine kraftfulde funktioner som dynamisk typning, affaldsindsamling og førsteklasses funktioner, hvilket gør det velegnet til AI-forskning, symbolsk beregning og hurtig prototyping.
Lisp blev skabt af John McCarthy i 1958 som en matematisk notation for computerprogrammer og som et praktisk middel til implementering af AI. Sproget blev afledt af lambda-kalkulus, et formelt system inden for matematisk logik og datalogi. Den første implementering blev udført på IBM 704, og kort efter opstod der mange dialekter, hver med sine egne funktioner og kompleksiteter.
Flere bemærkelsesværdige dialekter af Lisp er opstået over tid, herunder Common Lisp og Scheme. Common Lisp blev standardiseret i 1980'erne for at forene forskellige dialekter, mens Scheme, der lægger vægt på funktionel programmering og minimalisme, fik popularitet i akademiske kredse. Indflydelser fra Lisp kan ses i mange moderne programmeringssprog, især dem der understøtter funktionelle programmeringsparadigmer, såsom Clojure, Racket og endda sprog som Python og Ruby.
I dag er Lisp ikke blandt de mest populære programmeringssprog, men forbliver indflydelsesrigt, især inden for forskning, AI og uddannelse. Fællesskabet udvikler aktivt nyere dialekter som Clojure, der kører på Java Virtual Machine (JVM) og fokuserer på samtidig programmering.
Lisp anvender en unik syntaks, der bruger parenteser til at angive udtryk, med kode repræsenteret i symbolske udtryk (S-udtryk). For eksempel:
(+ 1 2)
Dette udtryk repræsenterer additionen af 1 og 2.
Funktioner i Lisp kan sendes som argumenter, returneres fra andre funktioner og tildeles variabler:
(defun square (x) (* x x))
(mapcar #'square '(1 2 3 4)) ; returnerer (1 4 9 16)
Lisp er dynamisk typet, hvilket tillader variabler at holde værdier af enhver datatype uden forudgående erklæring:
(setq x 10) ; x er nu et tal
(setq x "hello") ; x er nu en streng
Lisp har kraftfulde makrosystemer, der giver udviklere mulighed for at skabe brugerdefinerede syntaktiske konstruktioner:
(defmacro when (condition &body body)
`(if ,condition
(progn ,@body))
)
if
og cond
formerne letter kontrolflowet i Lisp:
(if (> x 0)
(print "Positiv")
(print "Ikke-positiv"))
Lisp behandler lister som grundlæggende datastrukturer:
(setq my-list '(1 2 3 4))
(car my-list) ; returnerer 1
(cdr my-list) ; returnerer (2 3 4)
Funktioner defineres ved hjælp af defun
konstruktionen:
(defun factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
Common Lisp inkluderer et objektorienteret system kendt som Common Lisp Object System (CLOS):
(defclass person ()
((name :initarg :name :accessor person-name)
(age :initarg :age :accessor person-age)))
(defmethod say-hello ((p person))
(format t "Hej, mit navn er ~A og jeg er ~A år gammel."
(person-name p) (person-age p)))
Lisp tilbyder en sofistikeret fejlhåndteringsmekanisme ved hjælp af handler-case
:
(handler-case
(/ 1 0)
(division-by-zero () (print "Opfanget division med nul!")))
Fortsættelser understøttes i nogle dialekter, hvilket giver programmet mulighed for at gemme og gendanne udførelsestilstande:
(call-with-current-continuation
(lambda (k)
(k 10)))
Flere integrerede udviklingsmiljøer (IDE'er) og kompilatorer henvender sig til Lisp-programmering. Populære valg inkluderer:
For at bygge et Lisp-projekt opretter du normalt en fil med en ".lisp" eller ".lsp" udvidelse. Ved brug af SBCL kan en typisk arbejdsgang involvere at indlæse dit projekt fra REPL:
(load "my-project.lisp")
For projekter, der bruger Quicklisp, en bibliotekshåndterer, kan afhængigheder nemt administreres og indlæses.
Lisp er især kendt for sine anvendelser inden for kunstig intelligens, symbolsk beregning og akademia, men det finder også anvendelse i:
Lisp sammenlignes ofte med:
Oversættelse fra Lisp til andre sprog udføres ofte ved hjælp af kilde-til-kilde oversættelsesværktøjer. For eksempel findes følgende værktøjer:
Hvert af disse værktøjer giver specifikke kortlægninger, der sikrer, at de grundlæggende funktionaliteter i Lisp effektivt kan repræsenteres i de målrettede sprog. For mere komplekse oversættelser kan manuel refaktorering være nødvendig, især for kraftigt makro-optimeret kode.