Почему несколько пространств имен? - PullRequest
13 голосов
/ 25 июля 2010

Каково обоснование решения о разработке отдельных пространств имен для значений и функций в Common Lisp? Какие аргументы за и против?

Ответы [ 5 ]

17 голосов
/ 25 июля 2010

См. Статью Ричарда П. Габриэля Технические вопросы разделения в функциональных ячейках и ячейках значений для полной академической обработки этого предмета.

8 голосов
/ 26 июля 2010

Common Lisp в основном является потомком оригинального Lisp 1.5, или, скорее, объединением его расходящихся диалектов. Первоначальный Лисп 1.5 был тем, что сейчас называется Лисп-2. Потому что это было в шестидесятых, и тот факт, что вы могли передавать функции другим функциям, был достаточно странным. Никто даже не подумал бы позволить им использовать одно и то же пространство имен. Почти любой язык, изобретенный сегодня с поддержкой функций более высокого порядка и анонимных функций, выбирает подход единого пространства имен. Включая Clojure, который в остальном ближе к Common Lisp, чем к Scheme.

Схема, как и Clojure, изначально не отличалась от диалекта Lisp 1.5, и для их целей это имеет смысл.

Конечно, в Clojure векторы, хэш-карты, множества и все, что также может быть применено к аргументам, поэтому в некотором смысле вектор в Clojure можно рассматривать как функцию, которая принимает натуральное число и выдает значение из .

7 голосов
/ 25 июля 2010

Хотя в теории может быть множество аргументов, я бы поспорил, что это в значительной степени философское происхождение. Scheme, Lisp-1, предпочитает элегантность, а не практичность, и выбрал тот же синтаксис define для переменных и функций, что делает естественным единое пространство имен (и поощряет функциональный стиль программирования). Common Lisp склонен отдавать предпочтение практичности и силе, а не элегантности, и был попыткой достижения консенсуса, поэтому, увидев, что существующее решение с двумя именами в целом принято и работает хорошо, оно было принято.

Однако на практике это в основном означает три вещи:

  • В Common Lisp (и других Lisp-2) вы должны использовать funcall много
  • В Схеме (и других Лисп-1) вы должны быть осторожны, чтобы не переопределить необходимые имена функций с переменными; например аргументы функции, такие как lst вместо list
  • В интернете будут аргументы

Это один из основных факторов, почему некоторые люди предпочитают один Лисп другому.

4 голосов
/ 25 июля 2010

Мне действительно нравится иметь несколько пространств имен (более двух даже);это облегчает работу пользователя и разработчика (реализация):

CL-USER> (defclass test () ())
#<STANDARD-CLASS TEST>
CL-USER> (defun test ())
TEST
CL-USER> (defparameter test 42)
TEST

CL-USER> (describe 'test)
COMMON-LISP-USER::TEST
  [symbol]

TEST names a special variable:
  Value: 42

TEST names a compiled function:
  Lambda-list: ()
  Derived type: (FUNCTION NIL (VALUES NULL &OPTIONAL))
  Source form:
    (LAMBDA ()
      (DECLARE (MUFFLE-CONDITIONS COMPILER-NOTE))
      (PROGN
       (SB-INT:NAMED-LAMBDA TEST
           NIL
         (BLOCK TEST))))

TEST names the standard-class #<STANDARD-CLASS TEST>:
  Direct superclasses: STANDARD-OBJECT
  No subclasses.
  Not yet finalized.
  No direct slots.

; No value

CL-USER> (make-instance 'test)
#<TEST {1005B1D601}>
CL-USER> (test)
NIL
CL-USER> test
42
CL-USER> 
0 голосов
/ 29 августа 2014

В дополнение к другим проблемам, упомянутым выше, наличие отдельного пространства имен для функций делает негигиеничные макросы CL гораздо менее вероятными для укуса пользователя макроса.В CL имя, привязанное к точке вызова, которая появляется в раскрытии макроса, будет иметь определение, используемое в точке вызова, , а не определение, используемое там, где определен макрос.Таким образом, в версии CL Lisp-1, если макрос расширяется до вызова функции LIST, и LIST были определены как переменная в точке, где был вызван макрос, макрос будет работать неправильно.(Обратите внимание, что gensyms не решают эту проблему, в отличие от обратной задачи, которую они решают.)

Этого не происходит в Scheme, потому что по умолчанию макросы Scheme гигиеничны: все имена, используемые в расширенииу макроса есть значения, которые они имели там, где определен макрос, а не там, где он используется.

...