Почему у elisp нет пространств имен?

40

В: Почему у elisp нет пространств имен, и как мы можем их получить?

У Elisp нет пространств имен, кроме глобального, что привело к соглашению о кодировании, заключающемуся в том, что все глобальные функции, переменные и константы имеют префикс с уникальным префиксом.

Помимо фактора раздражения, это также поразило меня как проблему, которая проявляется в связи с 1) постоянно растущим числом замечательных библиотек и пакетов и 2) продолжающимся существованием унаследованных функций и переменных, которые либо не соблюдают соглашение о префиксах, либо достаточно уникальны, так что на самом деле нет хорошего префикса, который они могли бы использовать. Это также означает, что периодические попытки рационализировать старый код (как при переходе от clк cl-lib) - это нетривиальный объем работы. (Хотя я рад за уборку, я все еще плачу каждый раз, когда набираю что-то вроде cl-find).

Я начал ковыряться, чтобы узнать, смогу ли я узнать, почему elisp все еще не имеет пространств имен после нескольких десятилетий использования, но был немного удивлен скромным урожаем. Вики - страница на пространствах имен является довольно короткой. У Ник Ферье есть немного более длительный подход к этой проблеме, и на emacs-devel также есть довольно свежая ветка . Существует старый поток Stack Overflow 2010 года, в котором обсуждается возможность использования макросов для реализации пространств имен; другой пример макроподхода можно найти здесь . Существует как минимум пара реализаций ( здесь и здесь , с описанием последних здесь), но они не видели много активности в течение нескольких лет, и я не сталкивался с библиотеками, которые их используют.

Я предполагаю, что, если бы добавить пространства имен было легко, это уже было бы сделано. Так:

  • Каковы технические барьеры для добавления пространств имен в elisp?
  • Не нарушит ли добавление пространств имен существующий код?
  • Является ли эта функциональность чем-то, что должно быть органичным для elisp (изменения в самом интерпретаторе), или она действительно может быть построена поверх макросов?
Дэн
источник
6
Вы могли бы взглянуть на это: github.com/Bruce-Connor/names Похоже, что это обратно совместимая (с текущим ручным способом разделения имен) реализация автоматических пространств имен. (И я на 99% уверен, что видел другую такую ​​библиотеку, позволяющую разработчику экспортировать подмножество функций с пространствами имен, о которых недавно упоминалось в каком-то блоге emacs, но я не смог найти его обратно).
Т. Веррон
2
Во-вторых, вы должны взглянуть на ссылку выше. Это очень недавний (выпущенный в прошлом месяце) и очень надежный макрос пространства имен. Я все еще прорабатываю несколько проблем с точки зрения совместимости с такими инструментами, как edebug, но пакет работает. Ответ на ваш вопрос - это очень длинное эссе (технических барьеров, с которыми я столкнулся, было много), но я постараюсь поместить его в сообщения блога в течение следующих недель.
Малабарба
1
Я думаю, пространства имен означают разные вещи. Я бы сказал, что в emacs есть несколько пространств имен: одно для переменных, другое для функций и макросов, другое для граней и тем и…
Харальд Ханче-Олсен,
1
@ HaraldHanche-Olsen ты можешь это сказать. В этом контексте он спрашивает, почему не существует пространства имен для каждого пакета.
Малабарба

Ответы:

28

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

Потому что это сложно, и никто не посчитал это достаточно срочным, чтобы сделать полный шаг. Это обсуждалось в списке разработчиков ранее (более одного раза), и были обещания исправить это после перехода на git.

Тем временем я написал собственное решение (список вариантов см. Ниже).

Каковы технические барьеры?

Прямо за дверью у вас есть 3 больших препятствия, которые вам нужно преодолеть, чтобы пространства имен даже имели возможность работать с текущим Emacs:

  • Вам нужно изменить способ интернирования символов (это самая простая часть).
  • Байтовый компилятор должен понимать пространства имен.
  • Генерация автозагрузки, используемая package.elпотребностями, должна понимать пространства имен.

Исправление этих трех вещей для работы, как бы вы ни реализовали пространства имен, не тривиально. Если вы посвящены только самой последней версии Emacs, это, безусловно, выполнимо. Если вы хотите написать какой-то пакет, который также поддерживает предыдущие версии (например, все 24 семейства), это превращается в один адский вызов.

Помимо этого, есть множество других дополнительных препятствий. Elisp великолепен, потому что обладает всеми возможностями доступных вам инструментов, и ВСЕ из них необходимо будет исправлять для работы с пространствами имен. Среди наиболее важных:

  • edebug
  • Eval-DEFUN
  • Eval-последней Sexp
  • тина

Это сломало бы много существующего кода?

Нет, если вы делаете это правильно.

Это что-то, что должно быть органическим или действительно может быть построено поверх макроса?

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

Malabarba
источник
1
Спасибо - это был очень информативный взгляд на проблему. Мне интересно ваше последнее замечание: ваше namesрешение. Интересно, есть ли основание полагать , что органические, встроенный в растворе приходят в не слишком отдаленном будущем, или если мы просто должны принять встроенную на решении , которое вы ввели.
Дан
1
@ Дан Да, есть. , Тем не менее, нет причин не принимать имена в то же время. Он полностью совместим с соглашениями Emacs, поэтому любой пакет, использующий Names, может в любой момент прекратить использование Names , и пользователь ничего не узнает.
Малабарба
Вы действительно должны добавить namelessв этот список :) Это блестящая идея, и она решает проблему очень аккуратно.
Климент
22

В прошлый раз, когда это обсуждалось на emacs-devel, обсуждение прекратилось, когда такие люди, как Ларс, указали, что им нравится быть способными M-x grepна что-то. Добавление пространств имен в Elisp не должно быть слишком сложным, но получение всех знакомых инструментов для правильной работы с ними - другая проблема.

Стефан
источник
Я думаю, что это можно легко «исправить», создав псевдонимы для наиболее часто используемых функций (или, может быть, всех их)
Джесси
1
Необходимость «grep» обычно проявляется при разработке пакета, поэтому вам нужно знать, где переменная / функция может использоваться в других пакетах, поэтому она может применяться к любой произвольной переменной / функции, а не только к конкретным важным. По этой причине добавление нескольких псевдонимов не будет иметь никакого значения. Еще одна причина, по которой mit не поможет, заключается в том, что добавление псевдонима не поможет вам найти применения, которые не используют этот псевдоним.
Стефан