Kategori:Common Lisp
Fra CodeWiki
| Common Lisp | |
|---|---|
| Paradigm | Multi-paradigme, funksjonelt, imperativt, objektorientert |
| Kom i | 1984, ANSI Common Lisp fra 1994 |
| Designet av | ANSI X3J13-komiteen |
| Typer | Dynamisk |
| Viktige implementasjoner | CLISP, SBCL, CMUCL, Allegro Common Lisp, Armed Bear Common Lisp, LispWorks |
| Påvirket | Python, Ruby |
Common Lisp er en dialekt av Lisp. Den første utgaven kom i 1984, men en revidert ANSI-standard ble utviklet i 1994. Common Lisp er den mest brukte Lisp-dialekten til programvareutvikling, og brukes i dag i mange forskjellige felt. Språket har i motsetning til den andre utbredte Lisp-dialekten, Scheme, et velutviklet og bredt standardbibliotek, et avansert objektsystem for objektorientert programmering, og et makrosystem for å skrive kode som, ved å bruke Common Lisp-språket selv, kan generere ny kode. Common Lisp er tilgjengelig gjennom mange implementasjoner, både kommersielle og open source. De kommersielle implementasjonene er solide programvareutviklingsmiljøer, med det meste som trengs for å utvikle applikasjoner i Common Lisp, som ekstrabiblioteker for grafikk og grafiske brukergrensesnitt. Om Common Lisp skal regnes som et tolket eller kompilert språk kommer helt an på implementasjonen. Noen implementasjoner, som CLISP, kompilerer kode til bytecode, mens f.eks. SBCL kompilerer til maskinkode.
Syntaks
Som andre Lisp-språk skiller Common Lisp seg fra andre språk med sin uvanlige syntaks med tilsynelatende alt for mange parenteser. Det viser seg dog at Lisps enkle syntaks er språkets sterkeste side. All Common Lisp-kode består av lister, der det første elementet i listen angir en funksjon eller operator som skal kalles, mens de resterende elementene er argumenter til funksjonen. Det klassiske Hello World-eksempelet ser slik ut i Common Lisp:
(format t "Hello World!~%")
Det første elementet i lista, format er funksjonen som skal kalles, og t og "Hello World!~%" er argumentene til funksjonen. t angir til format at den skal skrive teksten til standard-strømmen, som er til skjermen. format kan sammenlignes med C sin printf()-funksjon.
Elementene i en liste kan i seg selv være lister. Det er på denne måten komplekse uttrykk bygges opp:
(format t "2 + 3 * 9 = ~a~%" (+ 2 (* 3 9)))
Her har vi altså en liste bestående av fire elementer: format, t, strengen "2 + 3 * 9" og lista (+ 2 (* 3 9)) som i seg selv består av en funksjon (+) og to argumenter, hvorav det siste også er en liste bestående av funksjonen * og 3 og 9 som argumenter. Inni strengen forteller ~a at den skal erstattes med det neste argumentet til format. Dette programmet har, ikke uventet, utskriften 2 + 3 * 9 = 27. Allerede i dette enkle eksempelet ser vi at det fort blir en del parenteser å holde styr på. For å holde styr på koden er det derfor viktig å kode på en oversiktlig måte. De fleste editorer med en egen Lisp-mode kan hjelpe med dette ved å f.eks. lyse opp parenteser etter hvert som de lukkes.
Lister kan også forekomme som data, og manipuleres av kode. Hvis vi ser på listen (+ 2 (* 3 9)) i eksempelet ovenfor, kan vi enkelt forhindre at denne listen evalueres ("kjøres") som kode. Det gjør vi ved å sette en apostrof foran:
(format t "2 + 3 * 9 = ~a~%" '(+ 2 (* 3 9)))
Utskriften av dette programmet blir: 2 + 3 * 9 = (+ 2 (* 3 9)). Det er fordi vi forhindrer evalueringen av det siste argumentet. Dette faktumet -- at kode så enkelt kan gjøres om til data -- er en av de store fordelene med Lisp. Common Lisps makrosystem gjør det mulig å generere ny kode ved å konstruere lister, og deretter kjøre dem. Dette er ikke mulig i andre språk, fordi de har en mye mer komplisert syntaks, mens Lisp har alt i form av lister som enkelt kan manipuleres av kode. Dersom man kommer fra f.eks. C og savner en while-loopform, kan man enkelt legge denne til:
(defmacro while (test &body kode) `(do () ((not ,test)) ,@kode))
Denne makroen tar inn to argumenter, akkurat som en funksjon. Den tar inn test som er test-uttrykket som skal brukes for å avgjøre om loopen skal ta en ny runde, og kode som er koden som skal utføres hver gang loopen kjøres. Denne enkle makroen setter disse inn i et do-uttrykk, og deretter kjøres dette uttrykket. Nå kan vi skrive noe sånt som dette for å vise alle tallene mellom 1 og 10:
(let ((i 1)) (while (<= i 10) (format t "~a~%" i) (incf i)))
Her inngår while som en naturlig del av språket -- som om den var der fra før. Det som skjer under panseret her, når while-makroen kalles, er at den blir erstattet med koden
(do () ((not (<= i 10))) (format t "~a~%" i) (incf i))
... som er helt gyldig Lisp-kode, som benytter den innebygde do-operatoren.
Dette eksempelet er langt fra det beste på hva makroer kan gjøre, men det viser hvor lett en ny konstruksjon kan legges inn i språket. Når det gjelder å liste opp tallene fra 1 til 10 kan det selvsagt gjøres mye lettere:
(dotimes (i 10) (format t "~a~%" (1+ i)))
Artikler i kategorien «Common Lisp»
Det er en artikkel i denne kategorien.
