Каково объяснение позади проектного решения иметь отдельные пространства имен для значений и функций в языке Common LISP? Каковы аргументы в пользу и против него?
Common Lisp в основном является потомком оригинального Lisp 1.5 или, скорее, объединением его расходящихся диалектов. Первоначальный Лисп 1.5 был тем, что сейчас называется Лисп-2. Потому что это было в шестидесятые годы, и тот факт, что вы могли передавать функции другим функциям, был достаточно странным. Никто даже не подумает позволить им использовать одно и то же пространство имен. Практически любой язык, изобретенный сегодня с поддержкой функций высшего порядка и анонимных функций, выбирает подход единого пространства имен. Включая Clojure, который в остальном ближе к Common Lisp, чем к Scheme.
Scheme, как и Clojure, изначально не был диалектом, отличным от Lisp 1.5, и для их целей это имеет смысл.
Конечно, в Clojure векторы, хэш-карты, наборы и все, что также может быть применено к аргументам, так что в некотором смысле вектор в Clojure можно рассматривать как функцию, которая принимает натуральное число и выдает из него значение. .
Хотя в теории может быть много аргументов в пользу каждой стороны, я бы поставил на то, что это в основном философский вопрос. Scheme, Lisp-1, предпочитает элегантность практичности, и выбрал одинаковый define
синтаксис для переменных и функций, что делает единое пространство имен естественным (и поощряет функциональный стиль программирования). Common Lisp склонен предпочитать практичность и мощь элегантности, и это была попытка достижения консенсуса, поэтому, видя, что существующее решение с двумя пространствами имен широко принято и хорошо работает, приняли его.
На практике, однако, это в основном означает три вещи:
funcall
lst
вместо list
Однако это один из основных факторов, почему некоторые люди предпочитают один Лисп другому.
См. Статью Ричарда П. Габриэля Технические вопросы разделения в функциональных ячейках и ячейках значений для полного академического рассмотрения этого предмета.
Мне действительно нравится иметь несколько пространств имен (даже больше двух); это упрощает задачу для пользователя и компилятора (реализация):
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>