[235]> (setf f #'abs) ; I'm ok with this
#<SYSTEM-FUNCTION ABS>
Приведенный выше тип устанавливает переменную с именем f
для объекта функции - из функции с именем abs
.
[236]> (abs 3) ; This is fine
3
Выше вызывается функция abs
.
[237]> (f 3) ; Err due to sep. fn namespace. OK.
Вверху: нет функции с именем f
.
-- Err[1]: "Undefined function f" --
[238]> (#'f 3) ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"
Вверху: Common Lisp принимает только символы как имена функций, символы как имена макросов, символы как специальные операторы или лямбда-выражения какпервый элемент формы минусов.(function f)
не является именем функции.
Означает ли это, что системные функции обрабатываются иначе, чем пользовательские функции?
Нет.
[239]> (funcall #'f 3) ; seems very long winded...!
3
Выше вызывается функция funcall
с объектом функции из названной функции f
.funcall
затем вызывает этот функциональный объект с 3
в качестве аргумента.
кажется очень длинным сгибом
Это.
Почему я не могу выпустить ни (f 3), ни даже (# 'f 3)?Разрешается использовать четкие кавычки в качестве первого элемента формы?
Поскольку f
не называет функцию.Он называет переменную.#'f
также не является именем функции.Мы должны использовать имя функции (фактически символ).
Пространства имен
Common Lisp (как и некоторые другие диалекты Lisp) имеет два пространства имен для функций и для переменных.
Определение переменной foo
:
CL-USER 54 > (defvar foo 3)
FOO
Определение функции foo
:
CL-USER 55 > (defun foo (x) (* foo 10))
FOO
Мы можем вызвать функцию foo
со значениемполучено из переменной foo
:
CL-USER 56 > (foo foo)
30
Как получить объект функции из глобального имени функции:
CL-USER 57 > (fdefinition 'foo)
#<interpreted function FOO 4060001CAC>
CL-USER 58 > (symbol-function 'foo)
#<interpreted function FOO 4060001CAC>
То же, что и выше, но с коротким обозначением:
CL-USER 58a > #'foo
#<interpreted function FOO 4060001CAC>
CL-USER 59 > (function foo) ; works also for local functions
#<interpreted function FOO 4230008AAC>
Как получить значение из глобальной переменной:
CL-USER 60 > (symbol-value 'foo)
3
Или просто использовать переменную:
CL-USER 61 > foo
3
Некоторые положительные значения:
Положительный: имя не конфликтует.
Мы можем написать
(defun foo (list) (list list))
и не нужно писать
(defun foo (lst) (list lst))
Положительный: более простая компиляция
(let ((list 3))
(list 1 list 3))
Выше никогда не будет ошибки в Common Lisp.На схеме это будет ошибка: 3 is not a function
.