Почему несколько пространств имен?

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

13
задан Rainer Joswig 2 June 2013 в 08:16
поделиться

4 ответа

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

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

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

8
ответ дан 1 December 2019 в 19:22
поделиться

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

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

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

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

7
ответ дан 1 December 2019 в 19:22
поделиться

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

17
ответ дан 1 December 2019 в 19:22
поделиться

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

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> 
4
ответ дан 1 December 2019 в 19:22
поделиться