вторник, 10 сентября 2013 г.

Куда может завести "свой DSL". Часть 3. Резюме.

Как я сказал в предыдущей части, неразрешимых проблем с языком не было. Более того, его пытались даже использовать для написания триггеров уровня приложения, целей экспорта данных из наших систем в другие.
Но шло это всё с большим "скрипом", поскольку "отчётная заточенность" языка давала о себе знать на каждом шагу.
Внимательный читатель сразу вскинется: "Позвольте! Так и должны быть проблемы! Ведь DSL в силу своей domain-specific совершенно не предназначен для решения задач из другой предметной области!" и, возможно, в запале добавит: "Для другой предметной области нужен другой DSL!"
- Ну да, конечно... Должен... Не слишком ли много DSL-ев в одном приложении? Своих компиляторов для них, своих исполняющих сред? Или даже "просто интерпретаторов" (как это "просто"?). По мне - так много. Тем более, что я знаю, что все подобные проблемы можно решить средствами одного скрипт-языка, вместо того, чтобы прибегать к "магии" LEX/YACC.
Если Вам нужна domain-специфика, просто создайте соответствующий модуль или семейство модулей для скрипт-языка. Нужен русский язык в идентификаторах? - Не стесняйтесь - современные скрипт-языки позволят и это.

В любом случае, дорабатывать язык для поддержки в его контексте новой функциональности не было ресурсов, да и трудно себе было представить, как это сделать. Резкое падение интереса к языку совпало с выводом из эксплуатации наших 16-разрядных приложений, в среде которых он разрабатывался, и замене их на 32-рарядные версии. Нет, не было никаких проблем с его переводом языка в 32-разрядную среду, это даже было почти автоматически проделано, просто... Просто его место занял более адекватный задаче инструмент. Интерактивный. Такой, каким может воспользоваться и пользователь (прежде всего, для него он и разрабатывался) и наш сотрудник из отдела аналитики, который разбирается в нём лучше программистов, которые дорабатывают функциональность этого инструмента.
"Закодированные" на языке отчёты частично утратили актуальность, частично - были переведены на интерактивный генератор.

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

Начну с того, что работы над интерактивным генератором отчётов начались практически сразу после того, как язык генерации отчётов был доведён до рабочего состояния. Т.е. для состояния, когда мы могли приступить к разработке отчётов, а не исправлению ошибок в генераторе. Это был 1994 год.
В 1997 году интерактивный генератор отчётов уже существовал и активно применялся, хотя сфера его применения, в основном, ограничивалась относительно простыми табличными отчётами (по-простому, это когда в результат попадает содержимое одной таблицы, пусть слитой с другими несколько раз) и, разумеется, "вычислительными", на которых я остановился в предыдущей части.
Интерактивно он позволял приблизительно то, что обеспечивают все интерактивные генераторы отчётов: настроить источники данных, ввести параметры, ну и определить "шаблон" в который следовало поместить результаты.
Ничего необычного. Ну, разве что, это всё делалось в runtime основного приложения сотрудником отдела аналитики или конечным пользователем, знакомым с нашими технологиями.
Скажу дополнительно, что параметры отчёта можно было указать на этапе дизайна (в контексте основного приложения) и, даже связать с доменами БД. При запуске отчёта автоматически строилась форма ввода этих параметров. Ну и настройка источников данных использовала, существовавший у нас к тому моменту, интерактивный генератор запросов. Кроме того, обеспечивалась привязка "основного" (т.е. исходного) источника данных к DBGrid, в контексте которого мог быть вызван отчёт. Ну, чтобы сделать его либо по выборке, отображаемой в DBGrid, либо для текущей записи в нём.
Где-то в 1996-97 году появилось чёткое осознание того, что разработка интерактивных отчётов обходится существенно дешевле, чем их программирование. Главным образом потому, что работая с интерактивным инструментом, в котором гораздо меньше степеней свободы, решения формируются проще, и меньше вероятность ошибки, чем в случае, если приходится иметь дело с исходным кодом.
Приятным бонусом было также и то, что пользователь совершенно не обязан был уметь программировать для того, чтобы средствами дизайнера отчётов, встроенного в наши приложения, получить тот отчёт, какой ему требовалось. Ну или близкий к тому.
Таким образом, программисты были практически полностью вытеснены из процесса производства отчётов. "Практически" потому, что требовалось всё же исправлять ошибки и добавлять новую функциональность в интерактивный генератор отчётов. С этим успешно справлялся один человек. Ещё два знают, "куда смотреть" в случае, если возникнут проблемы, а первый, скажем, в отпуске.
Когда выяснилось, что есть отчёты, в которых требуется специальное поведение, которое трудно описать в терминах интерактивного генератора, мы просто подключили в отчёты Python.
После этого действия не осталось вообще никаких оснований применять язык генерации отчётов. Вместе с тем, с учётом сопровождаемых приложений, история этого языка продолжилась вплоть до 2005 года или около того.

Теперь думаю, мне имеет смысл резюмировать сказанное ранее. Чему меня научила эта история "собственного DSL"?
  1. Выделить описание предметной области отдельно от кода основного приложения (например, создать свой DSL для генератора отчётов) - хорошая мысль.
  2. Дать пользователю возможность сделать то, что ему необходимо в контексте приложения, управляя его функциональностью - отличная идея.
  3. Создавать свой язык (свой DSL) - дорого и рискованно с учётом его (языка) долгосрочного развития и вероятных изменений требований к нему.
Если есть потребность в DSL, то в первую очередь следует рассмотреть следующие варианты:
  1. Если DSL предназначен для "своих программистов", стоит обратить внимание на текучие интерфейсы.
  2. Если требуется именно язык, в котором должны присутствовать инструкции, предназначенные для программирования (ветвления, циклы и т.д.), то стоит рассмотреть возможность использования скрипт-языка.
    Современные LUA, Python, Ruby и т.п. очень хороши. Они подойдут и для пользователя, поскольку ему можно предоставить создавать только скрипт, избавляя от "магии" подключения других модулей и прочих лишних технических подробностей.
  3. Если язык предназначен для конечного пользователя, то следует стремиться сделать его интерактивным. Для пользователей-экспертов можно предусмотреть возможность обращения к скрипт-языку для описания специальных случаев.
Ну и, наконец, есть ещё один момент на котором я хотел бы остановиться.
Вы можете спросить меня: "Если бы у нас в 1993-м году был в распоряжении Python, стали бы мы "заморачиваться" на язык собственного изготовления?"
- Конечно нет. Мы использовали бы Python, "батарейки" которого содержат необходимую функциональность, в частности, по форматированию. Но точно так же мы занялись бы проработкой интерактивного генератора отчётов с тем, чтобы в итоге обеспечить симбиоз WYSIWYG дизайнера для 80% основной работы, и возможностей скрипт-языка для 20% специальных случаев.
Просто есть вещи, которые лучше делать интерактивно. Разрабатывать отчёты и формы ввода лучше средствами специальных приложений, в идеале, ресурсами тех сотрудников, которые имеют непосредственный контакт с пользователем и лучше всех знают, что именно ему нужно. То есть, ресурсами аналитиков.
Программист должен программировать, а заниматься дизайном должен аналитик.

Моей целью было не продемонстрировать, что концепция "своего собственного" DSL несостоятельна - нет. Просто IMHO DSL может принимать самые разные формы. Это может быть и специальная запись кода вашей программы (fluent-техника), и современный скрипт-язык, и продуманный интерактивный режим приложения, и диаграмма. Стоит ли при таком многообразии подходов обращаться к реализации собственного языка - решать только вам.

Ну, собственно, это всё, о чём я хотел рассказать.

3 комментария :

  1. Императивщина всё равно функциональнее декларативных ЯП. Взять тот же SQL - некоторые от него уже отказываются (HandlerSocket для MySQL), XSLT почти нигде не используется... Чтобы создавать свой DSL нужно очень чётко очертить область его применеия. К тому же это очень дорого. Поэтому пока придерживаюсь позиции, что стоит включить поддержку скриптовых языков и предоставить им API. Но Ваш редактор запросов - отличное подтверждение того, что DSL создавать всё-таки иногда надо :)

    ОтветитьУдалить
  2. «Императивщина всё равно функциональнее декларативных ЯП.»
    -- Да, но она и намного тяжеловестнее.

    «Взять тот же SQL - некоторые от него уже отказываются (HandlerSocket для MySQL)»
    -- Ну, "некоторые" отказываются не потому, что SQL - плохой DSL... :-)
    Просто есть класс задач, которые хотя и можно свести к этому DSL, эффективнее решаются, если этого не делать.

    «Чтобы создавать свой DSL нужно очень чётко очертить область его применеия. К тому же это очень дорого. Поэтому пока придерживаюсь позиции, что стоит включить поддержку скриптовых языков и предоставить им API.»
    -- Согласен. Впрочем, может зависеть от сложности самого DSL. IMHO, просто при определённом уровне этой сложности стоит задуматься об альтернативных путях, поскольку "развитие собственной языковой платформы не соответствует в интересам большинства компаний".
    Сложный DSL IMHO может быть эффективно заменён скрипт-языком. Но если так, зачем ждать, когда DSL станет сложным, почему сразу не начать со скрипт-языка?

    «Но Ваш редактор запросов - отличное подтверждение того, что DSL создавать всё-таки иногда надо :)»
    -- Но этот DSL не обязательно должен быть текстовым :-)
    Согласен.

    ОтветитьУдалить
  3. >>«Императивщина всё равно функциональнее декларативных ЯП.»
    >>-- Да, но она и намного тяжеловестнее.
    Согласен, но на примере того же MySQL: оверхед на разбор SQL, построение внутренних структур, выполнение оптимизаций (которые не всегда к месту) бывает настолько велик, что проще сказать "что сделать" нежели "чего я хочу". Однако, отказ от SQL приведёт к тому, что придётся учить внутренности каждой СУБД. SQL и взял именно своей кроссплатформенностью. Поэтому остановлюсь на мнении, что свой DSL - круто, прикольно, но только "поиграться", для реальной жизни надо очень осторожно подходить к решению о его создании - порой может быть дешевле реализовать поддержку скриптового языка.

    ОтветитьУдалить