Вопрос уже немного неправильный.
Мы говорим о разных вещах в Common Lisp:
- symbol : это структура данных в Lisp.Символ - это объект данных с именем, значением, функцией, пакетом и, возможно, другим.
В Common Lisp символ может иметь как значение, так и функцию (или макрос).
- a переменная является идентификатором значения в коде Лиспа
Существуют переменные верхнего уровня, определенные с помощью DEFVAR и DEFPARAMETER.Существуют также локальные переменные, определенные с помощью LAMBDA, DEFUN, LET, LET * и др.
(defun foo (i-am-a-variable) ...)
(defparameter *i-am-a-global-variable* ...)
- поименованная функция является идентификатором функции в коде Lisp.Именованные функции представлены на верхнем уровне DEFUN, DEFGENERIC и DEFMETHOD.Существуют также локальные именованные функции, определенные FLET и LABELS.
Пример:
(defun i-am-a-function (foo) ...)
(flet ((i-am-a-function (foo) ...)) ...)
Для дальнейшего усложнения названия функций и имен переменных являются символами в исходном коде.
Пример:
(type-of (second '(defun foo () nil))) --> SYMBOL
Давайте посмотрим на функции и переменные:
(defun foo ()
(let ((some-name 100))
(flet ((some-name (bar) (+ bar 200)))
(+ some-name (some-name some-name)))))
Выше код использует переменную и функцию с тем же символом висходный код.Так как функции и переменные имеют свое собственное пространство имен, столкновения не происходит.
(+ some-name (some-name some-name))
Выше этого значения означает, что мы добавляем переменную к результату вызова функции для переменной.
Это имеетпрактический эффект, что вы можете сделать что-то вроде этого:
(defun parent (person) ...)
(defun do-something (parent)
(parent parent))
Вам не нужно бояться, что имена ваших локальных переменных будут затенять глобальную (или локальную) функцию.Они просто находятся в разных пространствах имен.
В Scheme есть только одно пространство имен, и мы должны написать
(define (foo lst) (list 'a lst 'n))
, где в Common Lisp мы можем написать:
(defun foo (list) (list 'a list 'n))
В Common Lisp нет необходимости писать lst
вместо list
- потому что нет конфликта между локальной переменной list
и глобальной функцией list
.
Доступ кдругое пространство имен
Чтобы получить объект функции, хранящийся в переменной, вы можете использовать FUNCTION
.
(let ((my-function (function numberp)))
(funcall my-function 10))
(function foo)
можно записать короче как #'foo
.
FUNCALL
вызывает объект функции.
OTOH, если вы хотите сохранить объект функции из переменной в пространстве имен функции, есть только один способ:
(setf (symbol-function 'foo) my-function)
Также необходимо, чтобы объект был действительно функцией, а не чем-то другим (число, строка, ...).В противном случае вы увидите ошибку.
Побочным эффектом этого является то, что Common Lisp никогда не должен проверять, действительно ли в (foo bar)
FOO является функцией.Нет никакой возможности, что он может быть отличным от функции или неопределенным.