Protože je Elisp (nazývaný také Emacs Lisp) primárně určený pro práci v textovém editoru, obsahuje speciální funkce pro zpracovávání textu, ale také pro práci se soubory apod. Historie jazyka Lisp (LISt Processing) sahá do začátku padesátých let dnes již minulého století a během této doby se jazyk vyskytl v mnoha podobách a mutacích. Elisp je nejvíce inspirován tzv. Maclispem, ale najdeme zde i prvky Common Lispu.
Jak již název programovacího jazyka napovídá, pracuje Lisp převážně se seznamy.
Nejprve si vysvětlíme některé pojmy, které budou pro pokročilé uživatele Emacsu
patrně nudným opakováním. Symbol nil má v Elispu tři
odlišné významy: je to symbol pojmenovaný nil; představuje logickou hodnotu
FALSE; a konečně je to prázdný list. Symbolem představujícím logickou hodnotu
TRUE je symbol t. Oba tyto symboly ( nil a t) se vždy vyhodnocují samy
na sebe a nelze jich použít jako konstant. Dále se v jazyce Elisp vyskytují
běžné datové typy (označují se jako tzv. primitivní typy), například celá či
desetinná čísla, již zmíněné seznamy, textové řetězce, atd. Pro každý z
datových typů existuje odpovídající funkce, která kontroluje, zda je objekt
prvkem daného typu.
Pro většinu z těchto datových typů existuje celá řada vestavěných funkcí. Tak
například pro čísla jsou v jazyce Elisp dostupné všechny běžné aritmetické
operace (včetně například bitových operací, goniometrických funkcí apod.).
Podobně lze velmi dobře pracovat s textovými řetězci, seznamy, vektory atd.
Podrobný popis všech těchto funkcí lze nalézt v manuálu.
Jejich chování lze nejsnáze ověřit ve zvláštním Emacsovském bufferu *scratch*, který slouží pro vyhodnocování Elispovských
výrazů.
Vyhodnocování výrazů provádí lispovský interpret – tj. program, který na
vstupu obdrží lispovský objekt a „spočte" jeho "hodnotu
jako výraz“. Jak to dělá, závisí na datovém typu objektu. Interpret
provádí vyhodnocování částí programu automaticky, ale vyhodnocení lze také
„vynutit“ explicitně pomocí funkce eval. Vyhodnocování je rekursivní proces. Například volání
funkce nejprve vyhodnotí každý argument a poté vyhodnotí všechny formy (viz
níže) těla funkce. Provedení funkce je realizováno vyhodnocením definice
funkce.
Lispovský objekt, který se má vyhodnotit, se nazývá forma (form). Emacs
rozeznává tři základní typy forem: symboly, seznamy (listy) a ostatní objekty.
Například čísla patří mezi tzv. „samo-vyhodnocující“ se formy, kam
kromě nich patří všechny formy, které nejsou seznamem nebo symbolem. Tedy číslo
25 se vyhodnotí jako 25 a řetězec „linux“ se vyhodnotí jako řetězec
„linux“. Symbol se vyhodnocuje, jako proměnná. Výsledkem je hodnota
proměnné, pokud forma nějakou obsahuje (v opačném případě se signalizována
chyba). Například (setq a 123) nastaví hodnotu
proměnné na 123. Výše zmíněné symboly nil a t mají výsadní postavení a jejich hodnotu nelze takto
měnit. Neprázdný list je buď volání funkce, makro, nebo zvláštní forma. Každá z
těchto tří forem je vyhodnocována zvláštním způsobem.
Pokud je tedy prvním prvkem v seznamu lispovská funkce, vyhodnocuje se list
jako volání funkce. Toto je příklad volání funkce +:
(+ 1 2). Nejprve jsou vyhodnoceny zbývající elementy
- argumenty funkce, poté je volána samotná funkce a výsledkem vyhodnocení je
tedy v tomto případě číslo 3. Je-li na prvním místě seznamu objekt typu makro,
je list vyhodnocen jako volání makra. Zvláštní (speciální) formou jsou
primitivní funkce, u kterých se nevyhodnocují všechny argumenty (např.
podmínky, smyčky apod.). Vyhodnocení výrazu lze předejít uvozením výrazu
apostrofem (nebo též zvláštní formou quote).
Například tedy kód `(+ 1 2) se nehodnotí na součet
čísel 1 a 2 jako v předchozím příkladě, ale na seznam (+ 1
2).
Zavedením (nahráním) souboru obsahujícího lispovský kód se rozumí přidání jeho
obsahu do lispovského prostředí ve formě lispovských objektů. Emacs otevře
soubor, přečte text, vyhodnotí všechny formy a soubor uzavře. Soubor, který
obsahuje lispovský kód, se často nazývá knihovna. V Emacsu existuje mnoho
způsobů pro toto zavádění kódu. Počínaje funkcí autoload pro automatické zavádění, dále pak různé verze
load funkcí lišící se zejména v zadávaní parametrů či ve výsledku volání (viz
manuál).
Elisp obsahuje „kompilátor“, který převádí funkce napsané v
lispu do zvláštní reprezentace nazývající se byte-code, která urychluje
provádění programu. Tento byte-code je interpretován byte-code
interpretem a není proto třeba jej znovu překládat na jiné architektuře.
Takto „zkompilovat“ lze jednu konkrétní funkci, celý soubor nebo
dokonce několik souborů. Pokud máme k dispozici pouze nějakou knihovnu v podobě
byte-code, netřeba zoufat, neboť existuje „disassebler“, který
převádí „zkompilovaný kód“ do podoby čitelné pro člověka.
Další velmi silnou zbraní tohoto jazyka je přidávání rad (advice) již existujícím funkcím. Jedná se o velmi čistý způsob rozšiřování funkcí. Namísto rozšíření funkce přepsáním jejího kódu lze této funkci přidat tuto tzv. radu (advice). Každá funkce může mít více těchto „poradců“. Nejlépe si ukážeme tuto vlastnost na jednoduchém příkladě (převzatém z dokumentace Elispu). Představme si, že chceme rozšířit chování funkce previous-line takto: nachází-li si kursor na prvním řádku soubor,u vloží se při pokusu o posun na předchozí řádek řádek nový. A namísto přepsání původního kódu přidáme funkci radu:
(defadvice previous-line (before next-line-at-end (arg))
"Vloží prázný řádek při pohybu nahoru z první řádky."
(if (and next-line-add-newlines (= arg 1)
(save-excursion (beginning-of-line) (bobp)))
(progn
(beginning-of-line)
(newline))))
Tato část kódu definuje radu pojmenovanou
next-line-at-end. Jelikož je rada uvozena klíčovým
slovem before, spustí se před vykonáním samotné
funkce. Definováním této rady se nezmění chování funkce previous-line, radu je nutno ještě aktivovat: (ad-activate 'previous-line).
Existují celkem tři způsoby, jak hledat problémy a chyby v kódu Elispu v
závislosti na tom, kde se chyba vyskytuje. Pokud program právě běží, lze použít
debugger (edebug). Je-li problém v syntaxi (tedy Lisp nemůže program ani
přečíst), lze využít schopnosti Emacsu k nalezení chyby. Nedaří-li se program
„zkompilovat“ byte kompilátorem, je třeba chybu hledat v *Compile-Log* bufferu, kam kompilátor chyby zapisuje.
Velmi podrobný a dobře čitelný popis tohoto jazyka existuje v již zmíněné on-line
dokumentaci. Výhodou je předchozí znalost Lispu, nicméně Emacs poskytuje
velmi silné prostředky pro úvodní seznámení se s tímto jazykem. Navíc existuje
celá řada knihoven, které velmi usnadňují programátorskou práci. Při tvorbě
vlastních lispovských programů se doporučuje dodržovat určité konvence týkající
se například pojmenovávání globálních proměnných přidáním jednotného prefixu
pro danou knihovnu a celá řada dalších. Příště si povíme něco o w3 (tedy o tom,
jak brouzdat webem v Emacsu).
