Породження комбінаторних об’єктів.
(DEFUN list2 (LAMBDA (x y) (CONS x (CONS y NIL))))
та
(DEFUN list2 (x y) (CONS x (CONS y NIL)))
Функція DEFUN з‘єднує символ з лямбда виразом, після чого символ починає іменувати обчислення, яке визначається лямбда виразом. Значенням функції DEFUN є ім’я нової функції.
За допомогою структури LET, яка визначена в common.lsp, можна утворити локальний звя’зок. Значення змінним форми LET присвоюються одночасно. Ця структура має наступний вигляд:
(LET ((m1 a1) (m2 a2) ... (mN aN)) <форма1> <форма2> ... <формаN>),
яка в дійсності є лямбда викликом, де формальні та фактичні параметри знаходяться разом на початку структури:
((LAMBDA (m1 m2 ... mN) <форма1> <форма2> ... <формаN>) a1 a2 ... aN)
Наступні виклики еквівалентні:
$ (LET ((x 4)(y 2))(+ x y))$ ((LAMBDA (x y) (+ x y)) 4 2)
66
Функція типу NLAMBDA називається необчислюваною. Якщо викликається необчислювана функція, то їй аргументи передаються без обчислення — так, як вони стоять в рядку виклику. Пояснимо це на прикладі. Визначимо дві функції f1 та f2, які на перший погляд однакові:
(DEFUN f1 (LAMBDA (x y)(DEFUN f2 (NLAMBDA (x y)
(+ x y)) )(+ x y)) )
Якщо викликати (f1 5 6) або (f2 5 6), то результат буде однаковим – 11.
Нехай змінним k та l присвоєні деякі значення: (SETQ k 5 l 6). Тоді
$ (f1 k l)$ (f2 k l)
11помилка: (+ k l) / а не (+ 5 6), оскільки передані аргументи не обчислені /
Функція типу MACRO називається макро-функцією. Макроси є потужним робочим інструментом програмування. Синтаксис визначення макроса виглядає таким же чином як синтаксис визначення функції форми DEFUN:
(DEFMACRO <ім’я> <лямбда список> <тіло>)
Виклик макроса співпадає за формою з викликом функцї, але його обчислення відрізняється від обчислення виклику функції. В макросі не обчислюються аргументи. Обчислення виклику макроса складається з двох послідовних етапів. Спочатку відбувається обчислення тіла з аргументами (як і для функції). Цей етап називається розширенням або розкриттям макроса. На другому етапі обчислюється розкрита форма, значення якої повертається в якості значення всього макровиклику. Визначимо макрос PUSH1, який працює як відома нам функція PUSH (в дійсності PUSH є вмонтованим в середовище Лісп макросом).