Ответ 1
Общие Lisp имеют разные пространства имен для функций и значений.
Вы определяете функции в пространстве имен функций с DEFUN
, FLET
, LABELS
и некоторыми другими.
Если вы хотите получить объект функции как значение, вы используете FUNCTION
.
(defun foo (x) (1+ x))
(function foo) -> #<the function foo>
или короче:
#'foo -> #<the function foo>
Если вы хотите вызвать функцию, вы пишете (foo 100)
.
Если вы хотите вызвать функцию как значение, вам нужно использовать FUNCALL
или APPLY
:
(funcall #'foo 1)
Вы можете передавать функции и называть их:
(defun bar (f arg)
(funcall f arg arg))
(bar #'+ 2) -> 4
В случае DEFUN:
Это не (setf (symbol-value 'FOO) (lambda ...))
.
Это больше похоже на (setf (symbol-function 'foo) (lambda ...))
.
Обратите внимание, что два пространства имен позволяют вам писать:
(defun foo (list)
(list list))
(foo '(1 2 3)) -> ((1 2 3))
Не существует конфликта между встроенной функцией LIST
и переменной LIST
. Поскольку у нас есть два разных пространства имен, мы можем использовать одно и то же имя для двух разных целей.
Заметим также, что в случае локальных функций не используется символ. Пространства имен необязательно связаны с символами. Таким образом, для локальных переменных поиск функции с помощью имени символа невозможен.