Ответ 1
IIRC в Common Lisp не менее defun
является макросом (HyperSpec), то есть он может определять любую стратегию оценки вообще для его аргументов.
Возьмите эту функцию:
(defun sum-greater (x y z)
(> (+ x y) z))
Я понимаю, что в LISP первый элемент в списке всегда представляет собой функцию, которая будет выполняться на последующих атомах/списках. Итак, почему LISP обрабатывает x
в (x y z)
как функцию, выполняемую на y
и z
. Очевидно, это было бы нежелательно, но это было бы ожидаемым поведением.
Предположительно, функция, которая определяет defun
, как-то переопределяет стандартную оценку списка LISP списка? Если да, можете ли вы это подробно описать?
Спасибо
IIRC в Common Lisp не менее defun
является макросом (HyperSpec), то есть он может определять любую стратегию оценки вообще для его аргументов.
defun
является особенным, потому что это макрос. И поскольку макросы могут быть зависимыми от реализации, всевозможные черная магия могут произойти под капотом.
Lisp HyperSpec (Common Lisp) говорит, и я цитирую: "Ни один из аргументов не оценивается в момент расширения макроса".
Ваша презумпция верна. Defun обычно специальная форма или макрос
Вы можете скачать здесь базовое введение в Lisp:
Общий Lisp: Нежное введение в символические вычисления, Дэвид С. Туретцки.
Lisp и особенно Common Lisp имеет несколько форм Lisp:
вызовы функций
макросообщения
специальные формы
DEFUN - это макрос. Таким образом, макрос определяет, какие части оцениваются, а какие нет. Для ANSI Common Lisp это определено в стандарте и реализовано макросом DEFUN.
defun - это не функция, а специальная форма (или сводится к одному), и для этих целей механика оценки отличается. Подобные примеры были бы, если бы один из аргументов был полностью отброшен полностью без оценки вообще!