Что означает # в LISP - PullRequest
       70

Что означает # в LISP

27 голосов
/ 02 февраля 2011

Например, #'functionname, это необходимо?

1 Ответ

67 голосов
/ 02 февраля 2011

# 'имя функции в Common Lisp

Common Lisp и некоторые другие диалекты Lisp имеют более одного пространства имен. Здесь те для функций и значений разные. Чтобы получить значение функции имени, нам нужно написать:

(function functionname)

Поскольку это немного долго писать, есть более короткая запись:

#'functionname

Чтобы показать эффект, смотрите это:

(let ((foo 42))
  (flet ((foo () 'bar))
    (list foo (function foo) #'foo (foo))))

Выше определены локальная переменная FOO и локальная функция FOO. Оператор list возвращает значение из 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. Другие диалекты Лиспа, такие как Схема, не имеют такого разделения. В схеме имя может обозначать только одно значение.

Символ # .

Символ # используется для введения специального синтаксиса в 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 Sharpsign .

Common Lisp мог бы использовать другой синтаксис для векторов. Скажите [1 2 3]. Он также мог бы использовать другой синтаксис для комплексных чисел. Что-то вроде {1 2}. Но это не так. Зачем? Причина в том, что Common Lisp старается быть экономным с использованием символов в языке и оставляет такие символы, как [, ], { и } пользователю для его / ее собственных расширений синтаксиса. Часто пользователи Lisp разрабатывают встроенные языки и, чтобы сделать это немного проще, стандарт Common Lisp пытается свести к минимуму использование символов, а также предоставляет механизм макросов и диспетчерских макросов.

Чтобы сократить использование символов, используется один символ диспетчеризации #, и затем следующий символ определяет, что можно обозначить. #b для двоичных чисел. #x для шестнадцатеричных чисел. #c для комплексных чисел. #( для векторов. #' для имен функций. Плюс еще много.

Поскольку Common Lisp является программируемым языком программирования, этот синтаксис уровня символов может быть изменен пользователем. См. Функцию SET-DISPATCH-MACRO-CHARACTER .

...