Wartością wywołania funkcji defun jest lista będąca definicją funkcji. Lista napotkana w programie to tzw. forma, my będziemy używali określenia "wyrażenie listowe".
Lista jest to para <obiekt> <lista>.
class LISTA
- obiekt
- lista
Wywołanie funkcji skrajne-elementy: (skrajne-elementy listal).
Zmienne w LISP nie są deklarowane. W takim razie jak rozróżnić (na poziomie translatora / interpretera) procedurę od zmiennej? Translator tego nie odróżnia. Każdemu symbolowi można przypisać pewną wartość. Symbol, który w momencie wykonania ma przypisaną wartość jest z definicji zmienną.
Przykładowo wywołanie: (fl x y) , gdy nie jest określona wartość x, jest błędne. Każdy element wywołania z wyjątkiem pierwszego jest poddawany ewaluacji. Interpreter usiłuje wyznaczyć wartość tego elementu. Jeżeli trafia na wyrażenie listowe, to zachodzi to rekurencyjnie. Jeżeli jest to symbol, to interpreter usiłuje wyznaczyć wartość. Brak wyznaczonej wartości jest równoznaczny błędowi.
Wartości natychmiastowe uzyskiwane są przy pomocy wyspecjalizowanej funkcji quote. Przykładowe wywołanie: (fl (quote x) y). Skrótowa notacja: (fl 'x y). Czyli w sumie chodzi o cytowanie wartości natychmiastowej bez dalszego poddawania ewaluacji.
W LISP funkcjonuje RTTI. Np. jeżeli podamy zamiast listy atom, zwracany jest błąd, gdy oczekiwano atomu. W przykładzie błąd zgłoszony zostanie dopiero na poziomie podstawowych procedur, gdyż nie akceptują pojedynczych atomów.
Zwrócenie listy bez ostatniego elementu. Jest to implementacja własna procedury wbudowanej but-last:
defun my-butlast (lista)
if (endp (rest lista))
const (first lista)
(my-butlast (rest lista)
Omówienie:
endp zwraca prawdę, gdy lista podana jest pusta.