Актуальна ли Lisp-1 против Lisp-2 для языка со статическими типами?

(Это вопрос типа теории CS; я надеюсь, что это приемлемо.)

Дебаты Lisp-1 vs Lisp-2" касаются того, пространство имен функций должно отличаться от пространства имен всех других переменных, и это актуально для языков с динамической типизацией, которые позволяют программисту передавать функции как значения. Языки Lisp-1 (такие как Scheme) имеют одно пространство имен, поэтому вы не можете одновременно иметь функцию с именем f и целое число с именем f (одно будет затенять другое, как два целых числа с именем f). Языки Lisp-2 (такие как Common Lisp) имеют два пространства имен, поэтому вы можете иметь обе переменные f, но вы должны указать, какую из них вы имеете в виду, с помощью специального синтаксиса (#'f — это функция, а f — это целое число).

Мне кажется, что основная техническая проблема, необходимость устранения неоднозначности функции из целого числа, не является проблемой, если язык также статически типизирован (в отличие от большинства Лиспов). Например, если функция sort требует списка и функции меньше чем в качестве явной подписи,

def sort[X](list: List[X], lessThan: Function[X, Boolean])    // Scala syntax; had to pick something

тогда не имеет значения, находятся ли функции и все остальное в одном пространстве имен или нет. sort(mylist, myless) пройдет проверку типа только в том случае, если myless является функцией --- специальный синтаксис не требуется. Некоторые люди утверждают, что одно пространство имен более эстетично, чем два пространства имен, но я хотел бы сосредоточиться на технических вопросах.

Есть ли что-нибудь, что два пространства имен усложнили бы задачу или увеличили вероятность ошибок (или, наоборот, для одного пространства имен), предполагая, что рассматриваемый язык является статически типизированным?

(Я думаю об этом в контексте доменного языка, над которым я работаю, и я хочу убедиться, что у меня не возникнут проблемы в будущем. Было бы проще реализовать с двумя пространствами имен ( Lisp-2), и, поскольку он статически типизирован, нет необходимости в эквиваленте #'f. Я задал вопрос в общем, потому что хочу услышать общие моменты и, возможно, узнать о вопросах, которые я еще не знаю, чтобы задать.)


person Jim Pivarski    schedule 30.10.2013    source источник
comment
Итак, вы хотите выбрать, используете ли вы Lisp-1 или Lisp-2 в зависимости от типа? Это кажется одновременно запутанным и подверженным ошибкам.   -  person gsg    schedule 30.10.2013
comment
И почему было бы проще реализовать Лисп-2? В предоставленной вами ссылке указана стоимость проверки типов, но у вас нет этой проблемы, если ваш язык статически типизирован.   -  person gsg    schedule 30.10.2013


Ответы (1)


Одним из очень распространенных возражений против множественных пространств имен является то, что это усложняет формальную семантику наличия произвольного количества пространств имен. Одно пространство имен упрощает задачу. Следующим простейшим, как мне сказали (я таких вещей не пишу), является бесконечное число пространств имен — то, что я пытался сделать один раз и получил только полпути (см. здесь, если интересно, хотя я думаю, что в данном случае это не то, о чем вы просите). Когда вы ограничиваете его конечным числом пространств имен, формальная семантика становится беспорядочной, по крайней мере, так мне сказали. И, конечно же, это делает любой компилятор или интерпретатор немного более сложным. Это возражение колеблется между эстетическим и техническим, поскольку оно не основано на технической сложности как таковой, поскольку для создания нескольких пространств имен не требуется никакого сверхчеловеческого интеллекта, достаточно большого количества дополнительного ручного труда, а скорее возражение, что выполнение более сложного семантика означает больше кода, больше особых случаев, больше шансов на ошибку и т. д. Лично меня такие аргументы не впечатляют, я просто указываю на них, раз уж вы спрашиваете. Я думаю, вы обнаружите, что такие аргументы не являются фатальными и что вполне нормально продолжать то, что вы делаете, и посмотреть, к чему это приведет. Меня гораздо больше волнует опыт программиста/конечного пользователя, чем сложность разработчика. Но я упоминаю этот аргумент, потому что другие люди, которых я уважаю, похоже, считают, что это имеет большое значение, и я считаю, что это правильный ответ на ваш вопрос о сложности и склонности к ошибкам.

Кстати, обратите внимание, что когда мы с Габриэлем писали Технические вопросы разделения в функциональных ячейках и Value Cells, мне нужны были слова, которые помогли бы мне не говорить «подобно Scheme» и «подобно Lisp», потому что у людей были несвязанные причины для предпочтения Scheme, которые не имели ничего общего с пространством имен. Использование терминов «Lisp1» и «Lisp2» позволило мне не допустить превращения статьи в дискуссию между Scheme и Lisp и сфокусировать внимание читателей на вопросе пространства имен. В конце концов, ANSI Common Lisp получил как минимум 4 пространства имен (функции, значения, теги перехода, теги блоков) или, может быть, 5, если считать типы (которые в некотором роде похожи на пространство имен, но не в другие), но в в любом случае не 2. Так что строго это будет Lisp4 или Lisp5. Но в любом случае это все еще ужасает тех, кто предпочитает единое пространство имен, потому что любое произвольное конечное число, большее единицы, как правило, для них неприемлемо.

Моя личная рекомендация заключается в том, что вы должны разрабатывать язык в соответствии со своим личным пониманием того, что правильно. Для некоторых языков достаточно одного пространства имен. Для других нет. Просто не делайте этого только потому, что кто-то говорит вам, что любой путь должен быть правильным — это действительно ваш законный выбор.

Некоторые утверждают, что одно пространство имен концептуально проще, но я думаю, что это зависит от понятия простоты. Некоторые говорят, что чем меньше, тем проще (в нотации или реализации). Я утверждаю, что концептуально самое простое — это то, что наиболее изоморфно тому, как ваш мозг думает о вещах, и что ваш мозг может не всегда думать «маленькое» вместо «простого». Я бы привел по крайней мере один пример того, что каждый существующий человеческий язык имеет несколько определений одного и того же слова, почти все из которых разрешаются контекстом (из которых ваш вывод типа может быть одним из примеров контекстуальной информации), предполагая, что программное обеспечение предназначено для устранения неоднозначности такие вещи, и что ваш мозг тратит впустую часть своих естественных возможностей, если вы не позволяете ему заботиться о таких вещах. Возможно, этот контекстный вывод действительно усложняет реализацию вашего языка, но языки реализуются только один раз и используются много раз, поэтому есть все основания оптимизировать взаимодействие с конечным пользователем, а не с разработчиком. Это инвестиции, которые окупаются позже.

Настаивайте на том, чтобы думать о вещах так, как вы хотите. Больше беспокойтесь о том, чтобы ваш язык выглядел хорошо, и о том, реализуемо ли то, что вы хотите сделать, даже если это требует работы и дополнительной проверки кода. Ни одно языковое решение не подходит для каждого языка — языки — это экология, и важно, чтобы языковые элементы хорошо взаимодействовали друг с другом, а не чтобы языковые элементы соответствовали другим языкам. Действительно, если бы все языки были одинаковыми, было бы бессмысленно иметь несколько языков.

person Kent Pitman    schedule 18.01.2014
comment
Спасибо за подробный ответ! С тех пор, как я задал вопрос, я больше думал об этом и понял, что в статически типизированных языках пространство имен типов — это еще одно отдельное пространство имен — типы — это язык, который оценивается во время компиляции, то есть отличается от языка, который оценивается во время выполнения. Таким образом, язык со статической типизацией уже имеет более одного пространства имен. Напротив, язык с динамической типизацией, такой как Python, может помещать типы в то же пространство имен, что и переменные (например, объекты класса). Поскольку это один против (конечного) более чем одного, я соглашусь с ним. - person Jim Pivarski; 20.01.2014
comment
@Jim, ваши замечания об объектах, модулях и пакетах, действующих как пространства имен, напоминают мне: существует тонкое взаимодействие между макросами, пакетами и Lisp1/Lisp2, которое, как мне кажется, позволяет Common Lisp не спотыкаться о проблемы гигиены, которые постигли Scheme. Интриганы часто беспокоятся о фатальных недостатках Лиспа без гигиенических макросов. Я не согласен, но это, по общему признанию, субъективно. Я подробно обсуждал это в 1998 году на comp.lang.lisp с покойным Эриком Наггумом. - person Kent Pitman; 21.01.2014