A Lisp programozási nyelv (helyesebben nyelvcsalád) hosszú történetre tekint vissza. Eredetileg általános célú programnyelvnek tervezték az 50-es évek legvégén, de hamarosan a mesterséges intelligencia kutatás előszeretettel alkalmazott nyelvévé vált, amikor az 50-es, 60-as években ezen terület az első virágkorát élte. Ma a Lisp nyelveket számos területen alkalmazzák,Industry Applications using Lisp, alu.cliki.net és közkedvelt a számításelmélet oktatásában is.

A Lisp név az angol „List Processing” (listafeldolgozás) kifejezésre vezethető vissza (maga a lisp szó angolul pöszét, pöszítést jelent). A Lisp nyelvek fő adatstruktúrája ugyanis a láncolt lista. Az alapvető listakezelő műveletek az összes nyelvjárásban megegyeznek. Emellett közös sajátosság a zárójelezett prefix-jelölés, a futásidejű típusosság, a funkcionális programozásra jellemző jegyek (pl. rekurzív függvények, Lambda-kalkulus), és az, hogy a programkód adatként manipulálható, tehát végrehajtható. A változatok többsége értelmezőprogrammal fut, de sok közülük tartalmaz beépített fordítót is.

Tetszőleges Lisp nyelven írt program azonnal felismerhető a jellegzetes szintaktikájáról. A programkód ugyanis egymásba ágyazott listák, azaz zárójelezett, ún. S-kifejezések (S-expression, sexp) sorozata. Ennek a primitív szintaktikának köszönhetően a Lisp nyelveken írt programokhoz nagyon egyszerű elemzőt (parser-t) és kódot generáló (meta-) programokat írni, ugyanakkor emberi szemmel könnyű elveszni a nyitó- és csukózárójelek erdejében. A tömör kifejezőerején kívül a könnyű gépi elemezhetőség volt a másik oka a nyelv népszerűségének a 60-as években, amikor még sokszor monitor nélküli terminálokon vagy lyukkártyával, lyukszalaggal történt a bevitel, jellemzően nagygépes kötegelt végrehajtási (batch) környezetben, és nem mindenhol volt elegendő számítási kapacitás összetett, többmenetes fordító- és értelmezőprogramok futtatásához sem.

Formális specifikációjának első, 1958-ban készített változatával a Lisp a második legöregebb magas szintű programozási nyelv (a Fortran után). A megalkotása óta elmúlt bő 50 évben a nyelv sokat változott és számos nyelvjárással gazdagodott. A ma legelterjedtebb változatai az általános célú Common Lisp és Scheme nyelvek.

Történet

A Lisp (eredetileg az Information Processing Language, azaz Információfeldolgozó nyelv kifejezés rövidítése) volt az első, kifejezetten mesterséges intelligencia-algoritmusok leírására készített nyelv, amelynek alapötletét már 1955–56-ban megalkották, és amelyben már számos, a Lispben alapvető koncepció felbukkant, úgy mint a láncolt listák és a rekurzió.

A Lisp nyelvet John McCarthy alkotta meg 1958-ban a Stanford Egyetemen. Eredményeit 1960-ban publikálta („Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I.”). Cikkében rámutatott, hogy pár egyszerű operátor és egy függvények ábrázolására alkalmas primitív szintaktika segítségével teljes értékű, általános programozási nyelv alkotható. A matematikában ez a gondolat Alonzo Church újfajta matematikai logikai rendszere, az 1930-as és 40-es években kidolgozott lambda-kalkulus révén már korábban ismert volt.

Az első Lisp értelmezőt John McCarthy és Steve Russel készítette a Stanford egyetemen, 1963-ban. Először az IBM cég FSQ-32 típusú kezdetleges gépére írták, de a Stanford University már abban az évben új gépeket vásárolt, amihez John McCarthyék azonnal alkalmazkodtak: az első teljes (LISP 1.5) értelmező program szinte egyszerre készült el az akkoriban új PDP-1 és az IBM 7090 típusú számítógépekre. A korai IBM-gépek két alacsony szintű utasítása a nyelv két legfontosabb, listák felbontására használt függvénye lett: car (Contents of Address Register) és cdr (Contents of Decrement Register, olvasd, mint: cooder). A legtöbb ma létező Lisp nyelvjárás még mindig ezt a két operátort használja listák fejének, azaz első elemének, ill. a lista farkának, azaz az összes többi elemének a lekérdezéséhez.

Az egyre növekvő felhasználói tábor igényeinek és a kormányzati támogatásnak is köszönhetően az 1970-es években megszületett a Lisp-gép (Lisp-Machine), azaz a célzottan Lisp programok futtatására készített számítógép, amely már a gépi utasítások szintjén is "Lispül gondolkodik". A két legfontosabb project (több típusfejlesztéssel): 1974-től az MIT AI LAB-on a (DEC) "CONS" Lisp-Machine (MacLisp-változattal), és 1978-tól Stanford University-n a Xerox "Alto" gép (InerLisp-dialektust használt). Mindkét rendszer "mikrokód-programozott" volt, azaz a gépi Lisp utasításokat Mikroprogramozással, a processzor(ok) eredeti mikrokódjának átírásával valósították meg. Ezek sok területen felülmúlták a "klasszikus" gépeket, így az újabb Lisp-gép generációk fejlesztése egészen a '80-as évek végéig tartott. Mára a hulladékgyűjtő algoritmusok, a fordító- és értelmezőprogramok fejlődésének, valamint a memória- és számítási kapacitás robbanásszerű növekedésének következtében a Lisp-gépekhez hasonló dedikált megoldások feleslegessé váltak, de hatásuk a mai napig érezhető (pl. CAD- és egyéb komplex grafikus tervezőrendszerek makró-programozása, ahol a Lisp szinte lingua francává vált, ld.AutoLISP).

Az 1980-as és 90-es években komoly energiát fordítottak a szabványosításra, az egyre jobban eltávolodó nyelvjárások egyesítésére. Ennek, a több tucat Lisp-szakértő által több év alatt elvégzett közös munkának lett az eredménye a Common Lisp, amely magába foglalta a vele kiváltani kívánt dialektusok összes lényeges tulajdonságát, egyúttal követhető kompromisszuma lett a szakértők sokszor ellentmondó álláspontjának. 1994-ben az Amerikai Szabványügyi Hivatal, az ANSI nyilvánosságra hozta a nyelvjárást specifikáló szabványt (ANSI X3.226-1994). Ekkorra azonban a Lisp használata a 70-es évek virágkorához képest már jelentősen visszaszorult. Ez a "pihenő" egészen a 2000-es években új erőre kapott MI megjelenéséig tartottm ám azóta a Lisp – újult erővel és tucatnyi új változattal (Gauche, Arc, Chicken, Gambit stb.) – ismét növekvő népszerűséggel része a programozók kelléktárának.

A Lisp kifejező erejének és rugalmasságának köszönhetően gyorsan népszerűvé vált, de már nem csak a mesterséges intelligencia kutatói közösségek körében. A '60-as évek második felétől egyetemi területen gyorsan elterjedt más, a Lisp nyelvi eszközeivel és interaktív környezetével könnyen megfogalmazható feladatok megvalósításánál is (pl. adatbázis lekérdezés, tételbizonyítás, parserek és interpreterek, természetes nyelvek feldolgozása stb.).

Számos előnye mellett a Lispnek természetesen megvannak az árnyoldalai is: szintaxisa a kezdők számára a sok zárójel miatt nehezen átlátható; a bonyolult makrók segítségével megírt komplex függvényeket (ld. a "program-író programot író program"-ot..) néha még egy hozzáértőnek sem könnyű követnie, értelmeznie; nagy programok írásánál a hagyományos nyelvek fentről-lefelé programozási módszerével szemben a Lisp a lentről-felfelé irányú szemantikai felépítéshez illeszkedik, ami az egyéb nyelvekhez szokott programozóknak nagyon szokatlan; valamint a programok jelentős mennyiségű, részeredményként szolgáló adatot gyártanak, amelyek foglalják a memóriát. Ezen utóbbi még komoly problémát jelentett a 70-es évek memóriában és számítási kapacitásban szűkölködő számítógépeinek. Az elterjedt megoldás azonban elég hatékony: egy szemétgyűjtő (garbage collector) segítségével a rendszer bizonyos időközönként "rendet rak" (az ilyen, rövid időre lefoglalt memóriaterületeket a Lisp rendszeresen felszabadítja – azóta más nyelvek, pl. a Java is ezt teszi).

A számítógép-programozásban ma alapvető és teljesen általános esetszétválasztásos (ha … akkor …, egyébként …) vezérlési szerkezetet McCarthy vezette be a Lispben, amelyet aztán az ALGOL átvett és népszerűsített.

Ugyancsak "Lisp-találmány" a magyarra még le nem fordított "continuation" programozási megoldás, ahol is egyfajta késleltetett kiértékelés történik (a függvények a "végrehajtó kódot" (kifejezést) is paraméterként (argumentum)ként kapják, majd azt a megfelelő pillanatban "futtatják" (kiértékelik) – azaz a számításokat csak akkor fejti ki a rendszer, amikor azok eredményére szükség van)

A Lisp nyelv kapcsán lett először konferencia-szintű téma a dinamikus kontra statikus változók kérdése, ahol az idő a Common Lisp-et igazolta: immár egyre több újabb nyelv is a változók statikus (lexikális) tárolását/előhívását részesíti előnyben.

Szintén a Lisp az első megjelenése a modern funkcionális nyelvek egyik legfontosabb eszközének, a farok-rekurziónak, de számos más, az imperatív nyelvekben is használt fontos eszköz is a Lisp-megvalósítását követően terjedtek el pl. az interaktív programozási környezet, az elöl/hátul/a blokkban feltételt vizsgáló ciklusok, az adatok és eljárások bezárásának fogalma, a mintaillesztés is végző makrók, a függvényeket értékül adó-kapó függvények, a hulladékgyűjtő algoritmus, a fordítás programozó általi befolyásolása, optimalizálás és még számos egyéb programozási, rendszertechnikai és felhasználói lehetőség.

Szintaxis

A Lisp kifejezésorientált nyelv. Ez annyit tesz, hogy a legtöbb nyelvvel ellentétben a Lispben nincs különbség „kifejezések” és „parancsok” között, minden adatot és utasítást kifejezések formájában írunk le. Amikor az értelmező kiértékel egy kifejezést, eredményként egy értéket (vagy értékek listáját) kapunk, amely aztán beágyazható újabb kifejezésekbe, vagy akár kifejezésként maga is kiértékelhető.

McCarthy 1958-as cikke két kifejezéstípust különböztetett meg: Az S-kifejezéseket (S-expression, sexp), vagyis szimbolikus kifejezéseket, és az M-kifejezéseket, vagyis meta kifejezéseket, amelyek S-kifejezéseket alakítanak át újabb S-kifejezésekké. Ez utóbbi típus azonban nem talált támogatókra, és a legtöbb mai Lisp változat S-kifejezéseket használ mind az adatok, mind a kód manipulálásához.

Sokan kritizálták a zárójelek túltengését az S-kifejezésekben (ezt tükrözi a Lisp mozaikszó ironikus kifejtése, a „Lots of Irritating Superfluous Parentheses”, azaz „rengeteg irritáló és felesleges zárójel” is), de az igazság az, hogy az egyszerű, rendkívül szabályos szintaktika adja a Lisp legfőbb erejét: a lehetőséget, hogy a kódot adatként kezeljük. A legtöbb Lisp-rendszerhez használható szövegszerkesztő ráadásul a helyes és átlátható zárójelezés érdekében számozza vagy azonos színekkel jeleníti meg az egyes szintekhez tartozó nyitó- és zárójeleket.

Az, hogy mindent S-kifejezésekkel írunk le, nagy rugalmasságot biztosít a nyelvnek. Mivel a Lispben magukat a függvényeket is listákként definiáljuk, akként is tudjuk kezelni őket, és nem okoz technikai nehézséget programot generáló programok írása (ezt hívjuk metaprogramozásnak). Számos Lisp nyelvjárás ki is aknázza ezt a tulajdonságot, és lehetővé teszi makrók készítését, amelyek némi jóindulattal függvényeket generáló, paraméterezhető függvények.

A Lisp-ben egy listát zárójelekkel határolunk, az elemeket szóközzel választjuk el egymástól:

(1 2 "izé")

Ezen lista elemei az 1, 2, és az "izé" értékek. Az értékek típusa implicite adott (azaz nem kell – nem is lehet – külön megadni a típusukat): az első kettő egész, a harmadik pedig szöveges (ún. karakterlánc, string). Az üres listát a () kódsorozattal vagy a nil kulcsszóval írhatjuk le.

A kifejezéseket szintén lista alakban írjuk, mégpedig prefix jelölést használva. A lista legelső eleme egy művelet (angolul form), azaz egy függvény, operátor, makró stb. neve. A lista további elemei adják a művelet argumentumait. A list függvény például visszaadja az argumentumaiból alkotott listát, tehát a

(list 1 2 "izé")

kifejezés az (1 2 "izé") értékké egyszerűsödik. Függvény- vagy operátor-művelet esetén az argumentumok a művelet elvégzése előtt rekurzíve kiértékelődnek, értékük behelyettesítődik az eredeti kifejezésbe, amely csak ezután értékelődik ki, például a

(list 1 2 (list 3 4))