Egy kifejezés (lista vagy atom) feldolgozását az értelmező három lépésben végzi:
Ha egy kifejezést azért írunk fel, hogy az értelmező kiértékelje, akkor a kifejezést formának is nevezzük. Ha a beírt forma lista, akkor az értelmezőprogram ennek az első elemét egy függvény nevének tekinti, a lista további elemeit pedig — ha vannak — a függvény argumentumainak. A forma kiértékelésekor az értelmezőprogram a függvényt a legtöbb függvény esetében az argumentumok értékére alkalmazza. Először tehát kiértékeli az argumentumként megadott kifejezéseket, majd az argumentumok értékére alkalmazza függvényt. A forma értéke, azaz a kiértékelés eredménye a függvénynek az argumentumok értékének helyén felvett értéke lesz.
Például a (PLUS 5 6) függvénykifejezés értéke 11 lesz.
Későbbi funkcionális nyelvekben megjelent az ún. lusta kiértékelés. Ez azt jelenti, hogy csak akkor értékelődik ki egy kifejezés, ha szükség van rá, így egy változó értékének nem kötelező definiáltnak lenni. Ilyen a Lispben nincs!
Vannak beépített aritmetikai és listakezelő függvények.
Fontosak azok a függvények, amelyek egy szimbólumhoz hozzárendelnek egy értéket. Ilyen például a SETQ.
Itt a szimbolikus atomhoz, a kifejezés értékét rendeli. Ha azt akarjuk, hogy egy kiértékelés eredménye maga a kifejezés (pl. atom) legyen, akkor rakjunk elé egy aposztrófot.
A SETQ második argumentuma (csak a második argumentuma) kiértékelődik, és ez az érték lesz a függvénykifejezés értéke. Például a (SETQ ALFA (PLUS 3 6)) után ALFA értéke 9 lesz.
Az egyargumentumos QUOTE fgv. megtiltja az argumentumának kiértékelését, így lehet elérni, hogy ne értékelődjön ki a második argumentum ("jobboldal"). Például tegyük fel, a POCKOK-SZÁMA változónak a 6-ot adtunk értékül. Ekkor (SETQ A POCKOK-SZÁMA) esetén A-nak 6, míg (SETQ A (QUOTE POCKOK-SZÁMA)) után pedig a POCKOK-SZÁMA atom lesz az értéke. Hivatkozhatunk szimbólum értékének az értékére is az EVAL függvény segítségével.
Saját függvényt a DEFUN függvény segítségével definiálhatunk. Ennek szintaxisa:
A függvény neve nem tartalmazhatja az alábbi karaktereket: kettőspont, pontosvessző, nyitó- és csukó zárójel valamint idézőjel.
A paraméterlista esetén megengedett az üres paraméterlista is. A paraméterlistában megengedettek a következő kulcsszavak is: optional, rest, key.
Az optional kulcsszó után felsorolt paraméterek opcionálisak. Nem kötelező megadni. Ha valamelyik opcionális paraméter nincs megadva akkor az NIL-el helyettesítődik be.
A rest kulcsszó esetén az összes további paraméter egy listába fog bekerülni, majd ezt a listát a függvény kiértékelése során feldolgozhatjuk.
A key kulcsszóval az egyes paraméterekre a kulcsaik alapján is tudunk hivatkozni. Példák:
Ez sorra kiértékeli a listákat, majd az utolsó kiértékelés eredményével tér vissza.
Egy új scope-ot hoz létre, amiben az első listában szereplő változó-neveket a megfelelő inicializációs kifejezésekhez köti. Ebben az új scope-ban értékeli ki a törzsében szereplő kifejezéseket; a PROGN-hez hasonlóan a LET-kifejezés értéke az utolsó kifejezés értéke.
LET esetén az inicializáció párhuzamosan történik abban az értelemben, hogy az inicializációs kifejezések még nem látják az újonnan kötött változókat; LET* esetén az inicializáció szekvenciálisan történik. A következő példa segít ennek megértésében:
Van CASE is:
Az összehasonlítás EQ szerint történik. Ha egyik atommal sem egyezik meg a kifejezés értéke, és nincs OTHERWISE ág, akkor nil értéket kapunk. A CASE makró egy másik változata az ECASE, amelyben nem adhatunk meg OTHERWISE ágat, és ha nincs illeszkedő ág, akkor TYPE-ERROR szignált kapunk.
Egy feltételes kifejezést a COND függvény segítségével írhatunk le. A függvény általános alakja:
A feltételes kifejezés kiértékelése:
A feltételes kifejezéseknél használhatjuk a when és unless függvényeket is.
A when szintaxisa.
Az iteráció a nemfunkcionális programozási nyelvek egyik legjellemzőbb programozási eszköze. Segítségével a program egy részét többször is végre lehet hajtani. A LISP-ben azt nevezzük iterációnak, ha egy formát egymás után többször kiértékelünk, és egy meghatározott feltétel teljesülésétől függ, hogy meddig kell a kiértékelést ismételnünk.
A funkcionális nyelvek alapvetően a rekurzív függvényeket szeretik, de hatékonysági okokból (tár és idő) az imperatív nyelvekre jellemző iterációs "utasítások" is bekerültek.
A legegyszerűbb iteratív makró az RPT. Ennek segítségével azt írhatjuk elő, hogy egy S-kifejezés hányszor értékelődjön ki. (Ez a függvény az imperatív nyelvek szóhasználata szerint a számlálásos ciklusnak felel meg.)
A makró alkalmazásakor a második argumentum értéke annyiszor ismétlődik meg, amennyi az első argumentum értéke (az első argumentum egy szám, a második egy tetszőleges forma). A kifejezés értéke a második argumentum utoljára kapott értéke lesz.
A WHILE makró segítségével olyan ciklusokat szervezhetünk, amelyekben a kifejezés mindaddig kiértékelődik, amíg egy feltétel teljesül. A WHILE akárhány argumentumú, de legalább két argumentumot meg kell adni. Az első argumentum tetszőleges S-kifejezés — ez az iteráció ún. megállási feltétele —, amely mindig kiértékelődik. Ha értéke nem NIL, kiértékelődnek a további argumentumok is, majd ismét az első argumentum értékelődik ki és így tovább. Ez mindaddig ismétlődik, amíg az első argumentum értéke NIL nem lesz, ekkor a kiértékelés befejeződik. A WHILE függvény értéke mindig NIL.
Az UNTIL makró éppen a WHILE fordítottja. Argumentumait ugyanúgy kell megadnunk, mint a WHILE esetében, de a második és a további argumentumok csak akkor értékelődnek ki, ha az első argumentum — a megállási feltétel — értéke NIL. Ez ismétlődik mindaddig, ameddig az első argumentum értéke először bizonyul igaznak. Az UNTIL értéke ez az érték lesz.
Az újabb LISP rendszerekben megtalálható a DO makró is, melynek segítségével bonyolultabb ciklusokat építhetünk fel. A DO makróval mindazt meg lehet valósítani, amit az RPT, a WHILE vagy az UNTIL függvénnyel felírhatunk. Ugyanúgy, mint az UNTIL esetében, a DO alkalmazásakor is S-kifejezések értékelődnek ki újra és újra, egészen addig, amíg a feltételként megadott kifejezés értéken igaz nem lesz. A DO makró fontos lehetősége, hogy megadhatunk egy változólistát argumentumként. A változókhoz a változólistán értéket is rendelhetünk. A DO általános alakja:
Az első argumentum a változólista, amely kételemű allistákból áll. Az allisták első eleme tetszőleges szimbólum lehet, ezeket DO-változóknak nevezzük, a második elem pedig tetszőleges S-kifejezés lehet. A DO kiértékelésének kezdetekor minden változónak az értéke a hozzá tartozó S-kifejezés értéke lesz. A legtöbb LISP változatban a változólistán egyelemű allista is szerepelhet, ekkor a megfelelő DO-változó értéke kezdetben NIL.
A DO kiértékelése után a DO-változók elveszítik lokális értéküket, és ha volt előzőleg értékük, azt visszakapják.
A DO második argumentuma egy kételemű lista, amelynek elemei tetszőleges S-kifejezések lehetnek. A DO harmadik és esetleges további argumentumai tetszőleges S-kifejezések lehetnek, ezek alkotják a DO törzsét. Ha a megállási feltétel értéke NIL, akkor a törzset alkotó S-kifejezések egymás után kiértékelődnek. Az utolsó S-kifejezés után azonban nem fejeződik be a DO kiértékelése, hanem újra kiértékelődik a feltétel - és azt követően minden S-kifejezés - egészen addig, amíg a feltétel értéke igaz érték nem lesz. Ekkor értékelődik ki a megállási feltétel után álló tevékenység, és ennek értéke lesz a DO kifejezés értéke.
Az újabb lisp verziókban megtalálható a loop makró is. Ezzel széles lehetőségünk nyílik a különböző formátumú ciklusok használtára.
Végtelen ciklus esetén nem adunk meg kilépési feltételt. Például: (loop (print 'ciklus))
Lehetőségünk van egy loop ciklust egy tartományom belül is lefuttatni. (loop for x from 1 to 3 do (print x)).
Itt a to helyett használhatjuk a downto kulcsszót is ha változó értékét csökkenteni szeretnénk.
A below valamint above kulcsszavakkal is megadhatjuk, hogy meddig tartson az iteráció. (loop for x above 1 from 4 do (print x))
Ezen felül gyűjteményeket is bejárhatunk a loop makró segítségével. (loop for (item) on '(1 2 3) do (print item))
Az for-as-across segítségével járhatunk be array típusú adatszerkezeteket(pl a string is ilyen). Ilyenkor addig rakja be a változóba az elemeket amíg van elem az array-ben.
A DO makró esetén a törzs kiértékelése után, hacsak a megállási feltétel igaz nem lett, mindig végrehajtódik az iterációs lépés. Ez azzal a megkötéssel jár, hogy a törzsben szereplő kifejezések mindig ugyanabban a sorrendben értékelődnek ki. A PROG speciális forma ezzel szemben lehetővé teszi, hogy a kifejezéseket tetszőleges sorrendben értékeljük ki. A PROG-kifejezések a következő alakúak:
A kifejezés első eleme a PROG szimbólum, ezután következik a PROG változóinak listája. A PROG-változóknak kezdetben NIL az értéke. A változólista után tetszőleges S-kifejezés következik (címke, GO álfüggvény, RETURN álfüggvény). Ha a PROG törzsének utolsó S-kifejezése is kiértékelődött, és ez nem tartalmazott olyan GO-kifejezést. melynek hatására a kiértékelés a törzs valamely más helyén folytatódik, akkor a PROG kiértékelése befejeződik. A PROG kiértékelése akkor is befejeződik, ha a törzsben egy RETURN kifejezés kiértékelődik. Ennek alakja: (RETURN S-kifejezés).
Lehetőségünk van (Common) Lisp-ben lokális makrókat definiálni. Ezeket a MACROLET segtségével tudjuk megtenni. Hasonlóképp definiálható mint a DEFMACRO, csak nem globális környezetbe lesz definiálva hanem lokálisan.