LINUX.ORG.RU

Поругайте способ создания новых пространств имён

 


0

1

В юности я в основном писал на Паскале.

Там всё просто: ты пишешь

interface uses file1,file2;

После этого тебе доступны все имена, проэкспортированные в файлах (модулях) file1.pas и file2.pas. Если есть конфликт имён, то возьмётся первое попавшееся имя (стандарт вроде бы не даёт гарантий, что из file1). Но ты можешь написать file1.clashing_name и компилятор поймёт.

Всё было просто и устраивало. Потом я стал гораздо больше писать на лиспе и оказалось, что я трачу кучу времени и сил на управление пространствами имён, и всё никак не могу управиться.

В SQL есть иной способ сложения пространств имён. Там пространства имён для кляузы select образуются в каждом запросе.

select unique1,unique2,t1.clashing_name from table1 as t1, table2

Уникальные имена можно писать без префикса, а для тех, которые есть и в table1, и в table2, нужно указать префикс, иначе ошибка компиляции. Причём в запросе можно также назначить локальный псевдоним для имени таблицы.

Я хочу в своём языке применить именно этот способ сложения пространств имён. Собственно, я уже давно сделал свой макрос для определения пр-в имён, в котором эта возможность реализована, и пользуюсь им:

Но я смотрю, что в современных языках есть возможность импортировать символы по одному. Её я хочу исключить. Мотивация такова: это трудоёмко в поддержке. Если оказывается, что при импорте нужна только небольшая доля экспортируемых символов, то значит, у нас просто слишком большой модуль, который следует разбить на части.

Во время написания слов

from the_lib import symbol1, symbol2; 
мы, можно сказать, на лету создаём анонимный подмодуль модуля the_lib, экспортирующий два символа, а потом его целиком импортируем.

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

Если уж нужно создать подмодуль, то должна быть отдельная операция создания именованного модуля some_subset_of_the_lib, который только импортирует два символа из the_lib, а затем экспортирует их. В sql это делается через view.

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

Ругайте, а лучше хвалите подобный ход мыслей.

★★★★★

Последнее исправление: den73 (всего исправлений: 1)

Если оказывается, что при импорте нужна только небольшая доля экспортируемых символов, то значит, у нас просто слишком большой модуль, который следует разбить на части

Нет, не следует. Я вот из flexi-streams могу использовать только octets-to-string. И что мне разбивать?

anonymous
()

А так могу только ругать. Я на тебя смотрю, ты только созданием костылей занимаешься. Кто это потом поддерживать будет, когда тебе надоест?

anonymous
()
Ответ на: комментарий от anonymous

И что мне разбивать?

Не тебе.

den73 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Я вот из flexi-streams могу использовать только octets-to-string.

Ну и напиши тогда flexi-streams:octets-to-string. В моей библиотеке можно создать локальный псевдоним для пакета flexi-streams, хоть из одной буквы. Тогда будет f:octets-to-string.

den73 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

С этими костылями я уже прошёл некоторую дистанцию. Речь сейчас идёт не о костылях для CL, а о создании совершенно нового языка.

den73 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Я знаю, что значит слово кляуза, но я не знаю, как перевести clause. Думаю, мой перевод понятен.

den73 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Пункт слишком многозначен. И обычно пункт в своём контейнере один. А как быть с «multiple export clauses»?

den73 ★★★★★
() автор топика

Если имена короткие, то будешь больше разруливать клэшей, чем делать вызовов. Если длинные, то нафиг вообще нужны модули. Дробить модули не стоит, кроме того, это не всегда удобно (общие внутренние константы, типы и функции). Решать вопрос видимости должен импортирующий, т.к. экспортирующий тупо не знает, что требуется.

ведь я как-то раньше работал на Паскале и спокойно без этого обходился

210 GOSUB 1470 : REM Если задачи те же, то нафига новый язык?

arturpub ★★
()
Ответ на: комментарий от lazyklimm

выбирай нужное: http://docs.racket-lang.org/reference/require.html

Спасибо! Наворочено много. Гибкость не всегда во благо. Можешь сразу перечислить то, чем никто не пользуется?

Если короткие, то будешь...

Модули служат для декомпозиции системы. Пр-ва имён - для более краткого обращения. Это разные вещи. Но логично, чтобы у каждого модуля было имя, и чтобы он жил в своём пр-ве имён с таким же именем. Если попадутся короткие имена, то да, может быть плохо. Это содержательная часть твоего сообщения. Локальные псевдонимы позволят облегчить эту боль.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Можешь сразу перечислить то, чем никто не пользуется?

вообще по самому минимуму можно обойтись только prefix-in, единственная проблема - увеличивает количество писанины, так как к каждому имени из конфликтующего модуля придётся дописывать префикс

lazyklimm ★★★★★
()
Ответ на: комментарий от den73

multiple export clauses

Контекст не смотрел, может «несколько экспортирующих вложений». Обана как! Но хоть не безграмотное «кляуза»

anonymous
()

Хватило выходных, чтобы выдать очередную версию документа, хотя думал я над этим всю неделю.

описания пространств имён для моего язычка

Старался быть Чеховым. Может быть, будут у кого-нибудь какие-то конструктивные мысли на тему. Коротко говоря - пришлось почти всё переделать. Лично я более-менее доволен. Думаю, что это уже годно для версии 1.0.

den73 ★★★★★
() автор топика

Поругайте

Твои неймспейсы г... плохие!

slackwarrior ★★★★★
()
Ответ на: комментарий от den73

Старался быть Чеховым.

Но не получилось ни Чеховым, ни Успенским, ни Зализняком.
Хотя полезнее было бы Заходером.

местные клички пакетов

Погоняла же!

ABW ★★★★★
()
Ответ на: комментарий от lazyklimm

выбирай нужное: http://docs.racket-lang.org/reference/require.html

Похоже, дозрел до того, чтобы посмотреть сюда детальнее, потому что опять проблемы с модулями (а думал уже всё ок).

Я нашёл, что в ракете есть «коллекции» и ещё куча способов обращения к файлам. Я для себя придумал нечто аналогичное коллекциям, но назвал их «каталогами». Вопрос у меня такой.

Пусть есть одна коллекция с Земли, называется earth. Вторая с Марса, mars. Ничего не зная друг о друге, жители разных планет создали также коллекции date. И получилось, что есть модуль

asia в коллекции earth, который ссылается на модуль dow в коллекции date.

Также есть модуль olimpus в коллекции mars, который ссылается на модуль dow в коллекции date. Но имеется в виду марсианский календарь.

Можно ли в рекете, не меняя исходных текстов, разрулить эту ситуацию?

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

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Можно ли в рекете, не меняя исходных текстов, разрулить эту ситуацию?

да, обращения к модулям идут по относительным путям, потому никаких проблем

в mars/olimpus у тебя будет что-то вроде (require mars/date/dow)

lazyklimm ★★★★★
()
Ответ на: комментарий от den73

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

эмм, выше написал, всё по относительным именам, потому не вижу причин, по которым может возникнуть подобная ситуация

lazyklimm ★★★★★
()
Ответ на: комментарий от lazyklimm

Не, фишка в том, что date не внутри mars и не внутри earth. А получилось два разных «корневых» date от разных вендоров.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Вообще никаких проблем, потому что единственный вендор - это ты. Других не будет. Главное, следи за дозой, чтобы не случился второй корневой date от одного вендора.

anonymous
()
Ответ на: комментарий от lazyklimm

Относительные имена были просто /date в обоих случаях. Но на разных планетах они означали разное. А потом внезапно понадобилось сделать кросс-планетный проект.

Это ситуация глобально неуникального имени. Пример, наверное, слегка надуманный.

Можно представить более реальную ситуацию, когда понадобилось в один образ запихнуть две версии одного и того же. Положили lib-1.0 в одну папку, lib-2.0 в другую.

Дальше есть module1, которое читает lib, имея в виду 1.0, и module2, которое тоже читает lib, но имея в виду 2.0.

Вопрос, можно ли настроить ракетку так, чтобы каждый модуль читал то, что ему нужно. Если менять исходники - то понятно, что можно - просто указать нужные пути. И это будет две разные lib с разными именами.

А вот можно ли сказать: если я в module1, то lib = lib-1.0. А если я в module2, то lib = lib-2.0.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Но на разных планетах они означали разное.

С утра уже занюхал дорожку?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.