A2: первый прототип

Новый репозиторий для прототипирования: https://gitflic.ru/project/alekseinedoria/a2

Почему А2? Потому что ничего лучше в голову не пришло, язык в Вире я называл А0,А1 — язык для Вира-2 (который не вышел за уровень прототипа), так что пусть будет А2, пока название не пришло ко мне.

Первый прототип, см. папку «про», повторяет подход Вира, естественно, существенно упрощенный. Я не уверен, что так и должно быть, но с чего-то надо начинать. Текст на Тривиле, вот, так выглядит создание программы/схемы программы (про/про.tri), см. описания классов в модуле «схема»:

пусть к = схема.Верстак{ // корневой верстак
имя: «схема1»,
}
пусть и1 = печать.Печать{владелец: к} // первый инструмент
и1.настройки.задать( //  настройки инструмента
схема.Подключения, строки.ф(«$;:$;:$;», «.», схема.Запуск, «Печатать»),
«Умолчание», «Привет»,
)
к.инструменты.добавить(и1)

Потом это будет на декларативном языке.

Первая схема состоит из одного верстака и одного инструмента. Исполнение (любой) схемы:

к.подготовить к работе()
к.запустить()

Первый вызов — инициализация инструмента. В первой схеме, инструмент подключает свою команду «Печатать» к команде верстака «Запуск». Вторая команда «запускает» исполнение верстака, и, соответственно, подключенную команду «Печатать», которая печатает «Привет». Надеюсь, что в исходном коде все достаточно легко читается, поэтому не пытаюсь подробно пояснить здесь.

Вторая схема состоит из верстака и двух инструментов.

пусть к = схема.Верстак{
имя: «схема2»,
}

// Первый инструмент
пусть и1 = печать.Печать{владелец: к}
и1.настройки.задать(
схема.Подключения, строки.ф(«$;:$;:$;», «.», «Показать», «Печатать»),
«Умолчание», «Привет»,
)
к.инструменты.добавить(и1)
// Второй инструмент
пусть и2 = передача.Передача{владелец: к}
и2.настройки.задать(
схема.Подключения, строки.ф(«$;:$;:$;», «.», схема.Запуск, «Передать»),
«Команда», «Показать»,
«Аргумент», «Работает схема2»,
)
к.инструменты.добавить(и2)

вернуть к

Инструмент «Передача» получает уведомление «Запуск» и передает управление второму инструменту, который печатает текст. Взаимодействие инструментов задано через настройку (конфигурацию) каждого инструмент.

Упрощения по сравнению с Виром:

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

Что дальше? Медитация на тему

  • что является сущностным, а что лишним?
  • действительно ли нужно разделение верстак/инструмент?

Замечание: весь код инструмента сейчас написан явно, часть его должна быть реализована за счет «компиляторной магии».

6 комментариев


  1. Добрый день.

    Смотрю прототип.

    Первый вопрос, который я задавал и немного раньше — является ли в вашей модели готовая композиция компонентов {А1, А2, А3} самостоятельным компонентом, который можно как черный ящик опубликовать и потом заиспользовать в другом приложении или компоненте?

    Если да — то верно ли я понимаю, что сама эта А-компонента (схема?) включает в себя также и верстак, через который подключены компоненты/инструменты, и настройки этого верстака (разъемы)? Можно ли сделать схему/верстак инструментом?

    Тогда, чтобы подключать такоую компоненту в новую иерархию (схему), нужно, чтобы она выставляла свой верстак в доступ родителю, верно?

    Мне кажется, что даже для минимальной демонстрабельности и анализа того, что получается, нужно что-то чуть более сложное, хотя бы двухуровневое, и лучше не синтетическое («передача» + «печать»), а минимально-реалистичное. Пока видно, что механизмы есть, но непонятно, как же их использовать в практическом примере с библиотеками и переиспользованием.

    Еще я не понял, как фн верстак.запросить возвращает ответ, там выход типа Лог, а как само значение получать?

    Ответить

    1. 1) Да
      2) Да, верстак + схема + инструменты создают инструмент более высокого уровня
      3) Да, к родителю подключается верстак (верхний верстак, так как в компоненте их может быть много)
      4) Да, собираюсь сделать более интересный прототип

      фн (и: Инструмент) запросить*(команда: Строка, ответ := Строка, аргументы: …Строка): Лог
      Ответ возвращается в выходном параметре «ответ»

      Ответить

  2. Добрый день.
    Я еще попробовал нарисовать в виде компонентной диаграммы, что, с моей т.з. происходит в первом прототипе

    Получилось вот так:
    https://github.com/iamhere2/HLCD-Researches/blob/master/Trivill/dgm/Trivill-Proto-01.png

    Если я что-то неверно понял, попроавьте меня, пожалуйста.

    Я добавил названия интерфейсов умозрительно, как я бы разделил логически. Конечно, в коде этого нет.

    Что мне хочется отметить по этой структуре (в предположении, что я все понял верно):

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

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

    Ответить

    1. По схеме — не могу сказать что верно/не верно, потому что я её не понимаю. На мой взгляд, смешаны несколько точек зрения (структурная и динамическая, по крайней мере).

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

      >1. ничего не могу сказать, см. выше
      >2. … чрезмерно сложными и циклическими — может быть, задача прототипирования — упростить возможным образом — make it simple as possible, but not simpler.

      Ответить

  3. Не дает покоя вопрос, а как бы я предложил структурировать ту задачку, которая реализована в прототипе, т.е. просртое взаимодействие, но в варианте с высоким уровнем динамизма (сообщения, команды, вот это все).

    Нарисовал вот такое:
    https://github.com/iamhere2/HLCD-Researches/blob/master/Trivill/dgm/Trivill-Proto-01%20alternative%20design.png

    Что хочется отметить и пояснить:

    1. Мы сразу обозначаем, что приложение у нас — это тоже некоторый компонент. В данном случае приложение консольное, так что оно должно предоставлять вполне себе определенный инфраструктурой (статический!) интерфейс. Его должен кто-то реализовывать, и раз это А-компонента, то мы просто должны задекларировать, какой дочерний компонент будет это делать.

    2. Уже здесь появляется первый дочерний компонент «Вход», и его задача — просто реализовать статический интерфейсм консольного приложения (один синхронный вызов с аргументами, один exit code), перевести управление в дивный динамический мир :)

    3. То, что основная работа идет в динамическом гибком взаимодействии — определяется не языком, а Схемой. Т.е. схема компоненты может быть статическая, динамическая, смешанная — любая. Но мы по-любому должны сказать, кто обеспечивает внешние интерфейсы нашего компонента.

    4. Итак, схема отвечает за то, чтобы все внутренности создать и соединить. Если хотим динамику — ок, значит будет динамический Верстак (router), к которому с настройками маппинга сообщений подключены инструменты. Схема все это создает, наполняет, соединяет, конфигурирует.

    5. Сама схема при этом (ну это конструктор) — обязательная часть структуры, и похоже в ней есть что задать декларативно, и есть что задать императивно. Она получает управление только когда кто-то снаружи создает компонент.

    6. Интерфейсы инструментов упрощены максимально, у них есть реакция на уведомления. Событие «Подключено» тоже можно сделать уже динамическим.

    7. Интерфейс верстака _для_инструментов_ тоже минимален. Незачем им подключать самих себя, это все сделает схема, а им нужно только уметь отправлять сообщения.

    8. Настройки отображения сообщений в команды я бы положил не в инструменты, а в подключения инструментов к верстаку, т.е. про них должна знать сперва схема, а потом — верстак, а самому инструменту — зачем знать так много внешнего? Если я правильно понял логику маппинга, конечно, типа «по сообщению <> отправить сообщение <> в инструмент Печать»

    9. Каждый из дочерних компонентов в этой структуре (наверное кроме Схемы) может быть Д-компонентом, а может быть А-компонентом. Если это А-компонента, то у нее внутри есть Схема, а вот есть ли там ДинамическийВерстак — это ИМХХО большой вопрос. Может и нету, если там используется чисто статическая схема. Поэтому я не понимаю, зачем Верстаку иметь прямые ссылки на под-верстаки.

    10. Я пока опускаю вопрос, который меня ОЧЕНЬ беспокоит — вопрос «герметичности». Глядя на схему мы не можем сказать, может ли какой-то из дочерних компонентов начать писать что-то на диск или обращаться в сеть, если ему придет это в голову. Пока опустим этот вопрос. Пусть они пока могут достать эти неявные интерфейсы «из воздуха» (просто импортировав соответствующие модули и вызвав функции оттуда).

    Ну и еще раз призываю взять что-то чуть более сложное и реалистичное. Ну, там, «Морской бой» какой-нибудь или скажем «Интерактивный монитор температуры CPU/HDD/etc». Чтобы было пару уровней вглубь и проверка возможностей на полезность.

    Ответить

    1. Как только у меня высвободится немного времени и немного мозгов, … Пока не хватает даже на то, чтобы внимательно прочитать.

      Ответить

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *