Например, #'functionname
, это необходимо?
Что означает # в LISP
Ответ 1
# 'functionname в Common Lisp
Общие Lisp и некоторые другие диалекты Lisp имеют более одного пространства имен. Здесь те, для функций и значений, различны. Чтобы получить значение функции имени, нам нужно написать:
(function functionname)
Поскольку это немного длиннее для записи, есть более короткая нотация:
#'functionname
Чтобы показать эффект, см. это:
(let ((foo 42))
(flet ((foo () 'bar))
(list foo (function foo) #'foo (foo))))
Выше задается локальная переменная FOO
и локальная функция FOO
.
Оператор списка возвращает значение FOO
, затем значение функции FOO
, используя нотацию (function ...)
, затем то же самое с использованием короткой нотной записи, а затем значение фактического вызова функции FOO
.
(function foo)
и #'foo
являются одной и той же концепцией, но написаны по-разному. Оба относятся к локальной лексической функции с именем FOO
. FOO
вводится формой FLET
как локальная функция.
Lisp REPL возвращает что-то вроде этого:
(42 #<function FOO 4060008224> #<function FOO 4060008224> BAR)
Выше показано, что первый элемент действительно является значением переменной FOO
, а следующие два элемента - значения функций, функция привязана к FOO
. Последний элемент - это символ BAR
, возвращенный из вызова функции (FOO)
.
Это разделение пространств имен для нормальных значений и значений функций присутствует в Common Lisp, Emacs Lisp и ISLisp. Другие диалекты Lisp, подобные Схеме, не имеют такого разделения. В схеме имя может обозначать только одно значение.
# символ.
Символ #
используется для введения специального синтаксиса в s-выражениях. Вот несколько примеров:
#'functionname -> (function functionname)
#(1 2 3) -> the vector of the elements 1 2 3
#c(1 2) -> a complex number
#xFFFF -> a hex number
#b1111 -> a binary number
и многое другое. #
- это так называемый диспетчерский макросимвол.
ANSI Common Lisp HyperSpec описывает символ #
в в разделе 2.4.8 "Четкость".
Общий Lisp мог использовать другой синтаксис для векторов. Скажите [1 2 3]
. Он также мог бы использовать другой синтаксис для сложных чисел. Что-то вроде {1 2}
. Но это не так. Зачем? Причина в том, что Common Lisp пытается экономить на использовании символов в языке и оставляет пользователю такие символы, как [
, ]
, {
и }
для своих собственных синтаксических расширений. Часто пользователи Lisp разрабатывают внедренные языки и делают это немного проще, стандарт Common Lisp пытается свести использование символов до минимума, а также предоставляет механизм макросимволов и символов макроса отправки.
Чтобы сохранить использование символов, используется один символ отправки #
, а следующий символ определяет, что можно обозначить. #b
для двоичных чисел. #x
для шестнадцатеричных чисел. #c
для комплексных чисел. #(
для векторов. #'
для имен функций. Плюс еще много.
Так как Common Lisp - программируемый язык программирования, этот синтаксис уровня персонажа может быть изменен пользователем. См. Функцию SET-DISPATCH-MACRO-CHARACTER.