Схема использует единое пространство имен для всех переменных, независимо от того, связаны ли они с функциями или другими типами значений. Common Lisp разделяет их так, что идентификатор «hello» может ссылаться на функцию в одном контексте и строку в другом.
(Примечание 1: Этот вопрос нуждается в примере из приведенного выше; не стесняйтесь редактировать его и добавить один или отправьте по электронной почте оригинальному автору с ним, и я сделаю это.)
Однако в некоторых контекстах, таких как передача функций в качестве параметров другим функциям, программист должен явно различать, что он указывает переменную функции, а не переменную без функции, используя #'
, например:
(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)
Я всегда считал это чем-то вроде бородавки, но я недавно натолкнулся на аргумент , что это на самом деле особенность:
...
важное различие на самом деле заключается в синтаксисе форм, а не в
тип объектов. Не зная ничего о значениях времени выполнения
участие, совершенно ясно, что первый элемент функции формы
должен быть функцией. CL принимает этот факт и делает его частью
язык, наряду с макро и специальными формами, которые также могут (и должны)
быть определенным статически. Итак, мой вопрос: зачем вам
имена функций и имена переменных должны быть одинаковыми
пространство имен, когда основное использование имен функций должно появляться там, где
имя переменной редко бы появилось?
Рассмотрим случай с именами классов: почему класс с именем FOO должен предотвращать
использование переменных с именем FOO? Единственный раз, когда я буду ссылаться на
Класс с именем FOO находится в контекстах, которые ожидают имя класса. Если на
редкий случай, когда мне нужно получить объект класса, который связан с
имя класса FOO, есть FIND-CLASS.
Этот аргумент имеет некоторый смысл для меня из опыта; в Haskell есть аналогичный случай с именами полей, которые также являются функциями, используемыми для доступа к полям. Это немного неловко:
data Point = Point { x, y :: Double {- lots of other fields as well --} }
isOrigin p = (x p == 0) && (y p == 0)
Это решается небольшим дополнительным синтаксисом, особенно приятным благодаря расширению NamedFieldPuns
:
isOrigin2 Point{x,y} = (x == 0) && (y == 0)
Итак, к вопросу, помимо согласованности, каковы преимущества и недостатки, как для Common Lisp, так и для схемы, и в целом, единого пространства имен для всех значений по сравнению с отдельными для функций и нефункциональных значений?