#'callee
расширяется до (function callee)
, а 'callee
расширяется до (quote callee)
.
#'
ищет в пространстве имен функции.(Common Lisp - это 2-Lisp, что означает, что он имеет 2 отдельных пространства имен, что позволяет функции иметь то же имя, что и переменная / data - Scheme / Racket - это 1-Lisp, где функция и переменные имеют одно и то же пространство имен - то есть sthс определенным именем является либо функцией, либо именем для какого-либо другого объекта.)
'
нигде не ищет, но оценивает следующее имя символа как имя.
funcall
ищет имя аргумента в пространстве имен функции и возвращает назначенную ей функцию.Если вы делаете обычный вызов функции (callee 10)
, интерпретатор Lisp неявно ищет callee
из пространства имен функции, потому что первая позиция в списке, который выполняется, зарезервирована для имени функции.Когда имена функций задаются в качестве аргументов, в других позициях, отличных от первого, вы должны сначала применить к ним funcall
или #'
, чтобы интерпретатор знал, что это имя нужно искать в пространстве имен функции, а не внормальное пространство имен переменных.
Попробуйте это:
(defun d (x) x) ;; declares a function d in the function name space
(setf d 1) ;; declares variable d in the variable name space
(list d #'d d #'d)
;; returns:
(1 #<FUNCTION D (X) (DECLARE (SYSTEM::IN-DEFUN D)) (BLOCK D X)> 1
#<FUNCTION D (X) (DECLARE (SYSTEM::IN-DEFUN D)) (BLOCK D X)>)
;; when `#'` is given, the d is looked up from the function name space,
;; without, d is looked up from the normal variable name space
(d d)
;; the first position d gets looked up from the function name space but
;; the argument d from the variable name space
;; since the function d is the identity function and variable d has the value 1,
;; this evaluates the identity function on 1, thus to
1
(d #'d) ;; now the argument `d` is looked up from the function name space
;; thereby returning a function:
#<FUNCTION D (X) (DECLARE (SYSTEM::IN-DEFUN D)) (BLOCK D X)>