Во–первых, огромное спасибо всем вступившим в обсуждение собственного формата.
Отдельное, специальное спасибо (практически медаль) достаётся Степану Митькину, давшему потрясающе детальный и аргументированный построчный комментарий строго по основной теме разговора. Позволю себе именно по этой причине пополемизировать в первую очередь с ним
.
Степан Митькин писал(а):
line 11"skewers" - (означает шампуры) Неподходящий здесь термин.
Должно быть "branches" (ветки).
Не уверен. Всё–таки авторский вариант названия — «шампуры», это отражает их некоторое существенное отличие от просто «веток». Кроме того, я вслед за Фейнманом считаю, что введение “свежей”, отличной от всего предыдущего номенклатуры — очень хорошая и помогающая мышлению практика, ибо не “загрязняет” понимание нерелевантными контекстами из прошлых инкарнаций термина.
Степан Митькин писал(а):
line 22Содержимое иконы хранится в уже разобранном виде. Почему это плохо?
1. Получается, что каждый тип икон имеет разный набор полей.
Это неудобно для хранения диаграмм в базе данных.
2. Синтаксический разбор (parsing) перемешан с хранением схемы.
Это хороший повод для появления макаронного кода в будущем.
Современные БД — это далеко не только реляционные табличные системы. Наоборот, наибольший расцвет сейчас испытывают именно системы для хранения и обработки неоднородных данных, под общим (не очень удачным на мой взгляд) называнием «
NoSQL». Советую обратить внимание как минимум на
Apache Cassandra,
RethinkDB и
Redis.
Более того, даже в сугубо табличной реляционной PostgreSQL есть даже
специальный тип данных для хранения подобных JSON–документов с валидацией и
достаточно разнообразными функциями для обработки, а любые сложные выборки–преобразования возможны при помощи погруженного в базу
обработчика Javascript PLV8.
Второй пункт я, честно признаться, не понял. Сериализация — этап, всегда предществующий сохранению объекта (
а десериализация — последующий за загрузкой) в хранилище, будь то файл, принтер или удалённая БД. В большинстве известных мне сред программирования это разные этапы, но реализуются они в семантически близких местах (
например, сериализация — в классе, унаследованном от правильного “сохранятора” в Qt или наоборот, сохранение в БД — в классе, правильно описаном аннотациями сериализации в Java). При этом под
сериализацией обычно понимают сохранение либо в текстовом, либо в бинарном представлении, подразумевающем взаимнооднозначное восстановление структуры программных объектов при обратном преобразовании.
Если совсем кратко — сериализация и сохранение это два этапа, которые нужны удивительно часто и в 99,99% случаев реальной жизни следуют друг за другом, поэтому способы их “правильной” (“чистой”, “идеологичной” для используемого языка/среды, несвязной в смысле «decoupled», какой угодно ещё) реализации разработаны давно и используются повсеместно.
Степан Митькин писал(а):
line 36"default_answer", "alternative_answer" - больно напыщенно, по-учёному.
Я бы чего-нибудь попроще выбрал: yes_answer, no_answer.
Я специально передумал и заменил «yes» и «no» на «default» и «alternative». Значение этих “рукавов” — принципиально не логические (
в смысле значений логической функции), а компоновочные (
в смысле компоновки элементов диаргаммы). «default_answer» служит продлением уже идущего шампура и визуализирует наиболее вероятный алгоритмически путь развития событий. «alternative» — описывает ответвление, и по идее должен встречаться реже чем «default». Это, кстати, важно не только для графического представления алгоритма, но и для подсказки правильных ветвлений компилятору для генерации оптимального машинного кода тоже.
Степан Митькин писал(а):
line 37"text": "Да" - хранение излишней информации.
И так ясно, что "Да".
Если наклеечки "Да" и "Нет" переставлены, для хранения этого факта достаточно логической переменной. Иными словами, данные не нормализованы.
А китайцам как в таком формате надписи хранить? У них, насколько мне известно, нет универсального утвердительного/отрицательного слов, а в качестве выражения согласия/несогласия используется утверждение, производное от вопросительной фразы. Собственно, даже в русском есть такие фразы, вроде «Ты же не куришь, верно?» Ветка, на которой написано «Да», она куда ведёт? Лучше дать пользователю возможность написать «Курю» и «Не курю».
Вообще, “прибивать гвоздями” текст к логическим состояниям — это очень плохая практика для продуктов, которые потом придётся на другие языки мира локализовывать.
Степан Митькин писал(а):
line 78"clause" - это разобранное представление поля "text"?
1. Дублируем информацию.
2. Смешиваем синтаксический разбор с рисованием квадратиков.
Я опять–таки настаиваю, что текст на квадратике и логика, за ним сто
ящая — это не всегда одно и то же, и содержит в себе разную информацию. Поленюсь сейчас подбирать пример, впрочем — честно призна
юсь.
Степан Митькин писал(а):
Общие замечания:
1. Нет информации о координатах.
Мы же работаем с графикой! Да, координаты можно вывести автоматически.
Но это редко будет красиво.
Я ставил себе целью зафиксировать
алгоритмическое представление ДРАКОНосхемы, а не графическое.
Создатель каждого редактора может всю потребную ему дополнительную информацию запихнуть в произвольный набор джейсонвоских полей, благо формат это позволяет безболезненно. Особо острой потребности стандартизованно переносить характерные черты графического представления между различными ДРАКОНоредакторами я не вижу на данном этапе, сформировать выделенное представление алгоритма, стоящего за картинкой — во много раз более ценная задача с точки зрения встраивания ДРАКОНовской автоматизации в сторонние рабочие процессы.
Степан Митькин писал(а):
2. Древовидная структура документа. Почему это плохо?
- Мы имеем граф, а представляем его в виде дерева.
Документ имеет дополнительную сложность (степерь вложения элементов).
Но эта сложность не нужна. Она не соответствует природе предмета, который мы отображаем (граф).
- Плоскую структуру гораздо легче хранить в базе данных.
- Прочитать и записать её Элементарно.
- Если поменять связи между иконами, не нужно переписывать всё дерево.
Любой связный ненаправленный (а также — двунаправленный) граф можно алгоритмически преобразовать в дерево. Более того, если все вершины графа — различимы, то возможен взаимооднозначный алгоритм такого преобразования сначала в одну сторону, потом в другую.
Таким образом, с формальной точки зрения представление джейсоновского дерева и плоского графа ДРАКОНограммы эквивалентны.
Остаётся только “человеческая” сложность. Но мы в любом случае представляем двумерный объект (плоский граф) в виде одномерного (упорядоченная последовательность символов, то есть текст в файле), то есть избыточная сложность “на чтении–письме” всё равно будет иметь место, вопрос только, в каком из программных компонентов она будет иметь место. И тут мне кажется, что нет никакого криминала положить её в явном виде в сериализационные механизмы, а не доверяться в этом автоматике систем вроде RDBMS.
Кроме того, про хранение JSON–документов в базах данных (всплывало уже выше) я могу рассказать сколь угодно подробно, благо это достаточно часто использующаяся в промышленности техника.
Касательно пункта про связь между иконками — не уверен, что это вообще валидное возражение. Запись нескольких десятков килобайт на диск — абсолютно нечувствительная операция для современных ПК, передавать обновлённую схему по медленной внешней сети “на каждый чих” нет никакой необходимости (
для этого есть механизмы вроде rsync или diff, которые прекрасно адаптируются к текстовым слабоменяющимся локальным файлам небольшой длины), а для поддержания целостности софту давно уже следует использовать механизм “двойной записи” — когда на диск сначала пишется в сериализованном виде команда из «Undo–буфера», и только потом (возможно, после выполнения нескольких команд пачкой) — специальным образом помеченная сериализованная текущая версия документа. Последнее поведение, кроме ускорения дисковых операций на сохранение состояния, полезно ещё тем, что история изменений (Undo/Redo,
как это по–русски лучше всего сказать?) сохраняется полностью между сессиями работы с кодом. Такой подход, в частности, реализуют все современные онлайновые офисные пакеты, вроде Google Docs или Miscrosoft Office LIVE.
Илья Ермаков писал(а):
Вообще, конечно, Вы смешиваете в один уровень сам граф и его визуальное представление...
Вот это — очень похожая на мою мысль. Я ни в коем разе не хотел делать формат, задачей которого было бы однозначное расшифровывание графического представления ДРАКОНосхемы. А только лишь алгоритма, в этой схеме закодированного.
Всё остальное — опционально. То есть каждый ДРАКОНоредактор может насоздавать любых полей для сохранения собственной графической информации — и это не сломает парсинг/обработку. Стандартизировать такие вещи, на мой вкус, бессмысленно, пока у нас нет редакторов с устоявшейся и чётко зафиксированной (
например, в объёме коммерческих продаж) функциональностью.
Если хотите, могу добавить пример с подобными расширенными атрибутами узлов к себе в репозиторий. А ещё лучше — если эти атрибуты можно будет не выдумывать “от фонаря”, а где–нибудь посмотреть. Это, повторюсь, не сделает их обязательными для сериализации алгоритма, скрытого в ДРАКОНограмме, но поможет программистам понять перспективу и/или потестировать собственные парсеры.
Madzi писал(а):
Именно потому что шампур - прямая, не нужно хранить координаты икон, они должны высчитываться автоматически, потому что любое смещение с прямой убивает читабельность (наглядность).
Я тоже подходил к вопросу отображения десериализованного графа подобным образом. Однако же готов поверить разработчикам функционирующих ДРАКОНоредакторов, что им координаты зачем–то нужны, и задача эстетичного отображения автоматикой по каким–то причинам не решается.
Однако я повторю, что считаю вредной тащить эти вещи в стандартную запись, поскольку в разных средах ДРАКОНа наверняка необходимы разные наборы подобных метаданных отображения. А стандартизировать алгоритмы отрисовки ДРАКОНа среди разнородных редакторов — очевидно задача не только бессмысленная, но и вредная на современном этапе становления экосистемы. Поэтому (
по крайней мере пока кто–нибудь меня не переубедит) я буду выступать против включения любой специальной графической информации в описание текстового обменного формата ДРАКОНа.
Соответственно, этот комментарий относится и к следующей реплике:
Ильченко Эдуард писал(а):
Ещё как-то нужно хранить форматированный текст, да и форматирование самих икон. Ну там, цвет, перо, фон, шрифт ...
Повторюсь, абсолютно без проблем можно расширить набор полей для любых узлов. По стандарту JSON все избыточные для парсинга узлы должны игнорироваться, а недостающие — заменяться на значения типа null. Соответственно, десериализатор не должен ломаться в этих случаях, а должен просто прибегать к более–менее разумным “умолчальным” значениям.
Владислав Жаринов писал(а):
Дело в том, что есть ещё один путь - делать локально для конкретной предметки, но законченную систему.
Мне больше симпатичен подход той же системы
Cucumber (
по–моему, я где–то в этом обсуждении на неё ссылался уже), когда задача формализации предметной области наперёд не ставится, но недостающие элементы формального описания человекочитаемых алгоритмов прописываются post factum, с каждой итерацией покрывая всё большую и большую часть предметной области и потому требуя всё меньше человеческого вмешательства.
Я не настаиваю, впрочем, и это дело конкретной реализации ДРАКОНоредактора под конкретную задачу — работать в режиме гибкого текстового ввода чего угодно или в режиме конструктора для заранее сформированного DSL.