🏆 Рейтинг ІТ-роботодавців 2018: вже зібрано більше 13 000 анкет. Оціни свою компанію!
×Закрыть

Сделать сложное простым: что такое DSL, или зачем вам новый язык программирования

Сделать простое иногда во много раз сложнее, чем сложное
© Михаил Калашников

Здравствуйте, меня зовут Владимир Кожаев, я фрилансер-разработчик инструментальных средств (звучит почти как анонимный алкоголик). Этой статьёй я открываю цикл материалов, посвящённый разработке парсеров, трансляторов, компиляторов и тому подобных инструментов, облегчающих жизнь.

Действительно, зачем это нужен ещё один язык программирования? Понятно, он может быть нужен в каких-то НИИ при университетах, но обыкновенному бизнесу — какой толк от этой заумной мути? Вообще к чему столько разных языков, почему бы не использовать один единственный? Давайте разберёмся.

Почему бы не пользоваться одним языком

Жил да был в Великобритании выдающийся математик, логик, криптограф, и звали его Алан Тьюринг. В числе других открытий он придумал машину имени себя. Опуская подробности, скажем, что с помощью этой машины можно реализовать всё то же, что и с помощью любых средств программирования более высокого уровня. То есть любую программу на любом языке можно переписать с помощью этого достаточно простого средства. Тем более на любом языке типа Java или PHP можно реализовать эту самую машину.

Как следствие, существует критерий полноты по Тьюрингу-Чёрчу. Язык называется полным, если на нём можно реализовать машину Тьюринга. Все популярные языки программирования общего назначения (Java, C#, PHP, Python, Scala, JavaScript и так далее) являются полными. Что же это означает? Все популярные языки эквивалентны! Ну вот, смотрите: мы знаем, что все программы можно выполнить с помощью машины. Машину же, которая выполняет, можно написать что на PHP, что на C++. Получается, одну и ту же программу, записав её на языке машины Тьюринга, можно выполнить везде. А мы знаем, что так можно записать вообще любую программу.

На практике это означает, что программу на языке, скажем, JavaScript, поднатужившись, можно переписать на С++. Обратное тоже справедливо. Да, имеют значение библиотеки и фреймворки, но саму логику можно без проблем перенести с одного языка на другой.

Зачем тогда разные языки нужны, почему бы не пользоваться одним? В знаменитом романе Семюэля Дилэни «Вавилон 17» описан человек с выключенной частью мозга. Вместо этого он обучен искусственному языку, близкому по синтаксису к записям математических выражений. Он замечательно подходит для быстрого решения логических задач, компактен и удобен, но ограничен. Например, отсутствовали слова «я» и «ты». Поэтому парадоксы, такие как «Севильский цирюльник», мозг ограниченный «Вавилоном 17», сожжет или заставит обратиться к отключенной части. То есть языковые конструкции во многом определяют способ мышления.

Рассмотрим язык математики более подробно. Вот, например, описание доказательства теорем методом математической индукции:

Расшифровывается это так. Допустим, что:

  1. Установлено, что P1 верно. (Это утверждение называется базой индукции)
  2. Для любого n доказано, что если верно Pn, то верно Pn+1. (Это утверждение называется индукционным переходом)

Тогда все утверждения нашей последовательности верны. Обратите внимание: вместо нескольких строк текста имеем лишь одну строку со строгим определением, понятным любому математику.

Что же такое DSL

Domain Specific Language, или язык предметной области, — это язык, созданный для конкретной области применения. Построение его, или структуры данных, отражают специфику решаемых им задач © Википедия.

То есть, если человек знает свою работу, учить DSL не надо — достаточно взглянуть один раз, и всё понятно (см. пример с математикой). Также хороший DSL не требует больших знаний в теории и практике программирования. Во многих, например, нет циклов. В некоторых — условных операторов (типа «if»). Часто язык является не полным по Тьюрингу, то есть написать любую программу с его помощью нельзя. Опять же, вспомним язык математики или кванторов. Он используется лишь для описания теорем или для их автоматического доказательства. Писать web-сервисы с его помощью было бы затруднительно.

Примеры использования DSL

DSL используются очень по-разному. Рассмотрим несколько из них и постараемся понять, в каком же случае следует их использовать.

Резак лазера

Положим, вы — инженер кораблестроитель и хотите вырезать большущую деталь для корпуса судна. Раньше это делалось так: на плотном картоне или фанере вычерчивали детальки, вырезали, прикладывали к листу стали, и люди, которых называли кернильщиками, ползали по листу и набивали по контуру выкройки впадинки. Дальше газорезчик шёл по контуру и вырезал. Представляете, что будет, если резчик с утра перебрал? А можно сделать это автоматически, чтобы робот считывал чертёж и сам ехал по листу, вырезая нужную деталь? Да, можно! Однако проблема в том, что траекторию его передвижения нужно как-то задать. Мол, поедь туда, опусти резак и дальше двигайся эдаким манером. Для этого нам нужны следующие команды:

  1. Двигаться из точки А в точку Б с выключенным резаком (помним, что прямая — кратчайшие расстояние между двумя точками).
  2. Двигаться с включенным резаком уже по заданной кривой (частный случай кривой — прямая). Для простоты ограничимся, собственно, отрезком прямой линии и участком окружности с заданным радиусом и центром. Поскольку положение резака задано предыдущими движениями, указать нужно лишь точку остановки. Для отрезка прямой — это конец отрезка. Для участка окружности — угол поворота и центр окружности.

Таким образом, в наиболее простом случае нам нужны только три команды:

MoveTo(x, y)
LineTo(x,y)
AngleTo(centerX,centerY, angle) 

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

Алгоритмический трейдинг

Трейдер редко ошибается дважды — обычно раза три или больше
© Из грустного опыта продавшего квартиру

Каждый хочет купить дешевле и продать дороже — вроде бы понятно. Но как определить правильное время для сделки, если завтра цена может вырасти или упасть? Решение принимается с помощью фундаментального (новости, анализ экономических и политических событий) и технического (экстраполяция стоимости ресурса на основании предыдущих данных). Признаки, по которым судят о поведении цены, теоретически не доказаны и не точны. То есть какая то связь с реальностью усматривается, но обычно берут несколько признаков и принимают решение о закрытии или открытии сделки, когда сигнал о покупке либо продаже подают все используемые индикаторы.

Кривая цены меняется очень быстро. Данные, полученные 15 минут назад, как правило, интересны только для историков. Деньги на бирже крутятся большие, так что потерять несколько сот миллионов долларов за минуту можно запросто. Поэтому человеческий фактор хорошо бы свести к минимуму. Но как это сделать, если общей теории поведения цены не существует и стратегии торговли трейдер выбирает их с помощью интуиции? Один из способов уберечься от ошибки — создать специальный язык с минимумом «шума». Оставить в языке только необходимое, безжалостно избавясь от возможностей, которые нам не нужны. Что же нужно для трейдинга?

  1. Понятно, что цена снега в Антарктиде и на экваторе, мягко говоря, отличается. То есть необходимо указать биржу, цены на которой мы исследуем.
  2. Нужно указать стратегию, с помощью которой мы будем торговать (их есть много разных).
  3. Для стратегии нужно указать параметры, специфические для каждой, и временной интервал, в течение которого происходит работа.
  4. Стратегии запускаются на серверах, каждый из которых работает с заданной биржей. Нужно задать время, в течение которого они работают, поскольку доступ к бирже бывает и платным.

Давайте посмотрим, как будет выглядеть эта стратегия на языке Java. Допустим, мы хотим получить сигналы о покупке/продаже валют на серверах трех бирж с помощью стратегий: «фибоначчи», «скользящее среднее», «преобразование Гильберта». Для простоты будем считать, что время измеряется в тиках, название биржи, на которой работает сервер, задается просто строкой, и торгуем мы валютами — меняем доллары, евро или ещё что-нибудь на украинскую гривню и обратно.

На первый взгляд, код выглядит хорошо, но, если приглядеться, в нём полно ошибок.

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

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

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

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

Преимущества предложенного примера очевидны. Во первых, текст стал лаконичным: сервера указываются ровно один раз. Стратегии — в непосредственной близости от сервера, на котором запускаются. Во вторых, мы избавляемся от ненужных подробностей. Трейдеру вовсе и не нужно знать, что такое Thread или что итоговая программа будет написана на языке Java.

Разработка игровой логики

Ошибка: робот погибает при попадании в него гранаты (именно от попадания, а не от взрыва). Д — дизайнер, П — программист.
Д: программисты всё сломали! почему так получается?!
П: естественно, так получается! потому, что у гранаты масса 100 кг! зачем вы это сделали?
Д: да?! а чтобы граната в воде тонула!
П: а почему она с нормальной массой не тонет?
Д: а потому что у воды плотность большая! (прим.: больше, чем у ртути)
П: а почему плотность такая большая?!
Д: а чтобы ящики деревянные плавали!
П: а почему они иначе не плавают?!
Д: а потому что у них масса 50 кг!
П: а зачем такая масса?!
Д: а иначе они некрасиво разваливаются!

Допустим, вы — геймдизайнер, и вам нужно создать сценарий для поведения робота. В начале стрелять, когда кончатся патроны — бежать. Программисты это, конечно, без проблем сделают. Но в определённый момент нужно изменить поведение — сделать так, чтобы робот в начале бежал и только когда догоняют — стрелял. А ещё — прятался за холмик или делал забавный финт ушами. Программист, конечно, снова сделает, но потратит время. При последующих переделках придётся опять его тревожить, и так без конца.

Более того, игры сейчас выходят на множестве разных платформ. Выпустили под Windows, и надо выходить на Vii, на планшетах, на smart TV и так далее. Каждый релиз приводит к переписыванию кода, который уже работает и оттестирован, хотя логика действий персонажей не меняется при переходе от устройству к устройству. Можно, конечно, использовать кроссплатформенные средства. Такие как Unity, или Haxe, но, как правило, проблема в том, что кроссплатформа работает одинаково плохо на всех устройствах. То есть хотелось бы сделать так, чтобы разрабатывать заново нужно было только специфические для конкретной платформы вещи, оставив логику без изменений.

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

Что же делать, учить дизайнера программированию? Но это две довольно разные и в каком-то смысле противоположные специальности. Хотелось бы сделать так, чтобы дизайнер достаточно простым способом без помощи программиста мог поменять поведение персонажей.

Конечный автомат

Представим игровую логику в виде состояний персонажа и переходов между ними. К примеру, у робота может быть три состояния: «бежать к игроку», «стрелять» и «искать патроны», когда они кончились. Действия происходят при входе в состояние, выходе из него, переходе от одного состояния в другое и когда состояние между через определенный метод времени не изменилось. Можно описать состояния и переходы с помощью JSON, или XML и потом воспользоваться шаблоном проектирования «машина состояний», как это описано в банде четырёх. XML для описания представлен ниже:

<state name="run_to_enemy">
	<before methods="do_something_before"/>
	<after methods="say_hi"/>	
	<in_process methods="say_hug"/>
	<transitions>
	<transition name="shoot" methods="run">
		<condition function="near_the_enemy && have_bullets"/>
	</transition>
	</transitions>
</state>

<state name="shoot">
	<before methods="do_something_before_shoot"/>
	<after methods="say_hia"/>	
	<in_process methods="say_bum"/>
	<transitions>
	<transition name="run_to_bullets" methods="hi">
		<condition function="no_bullets"/>
	</transition>
	</transitions>
</state>

<state name="run_to_bullets">
	<before methods=""/>
	<after methods=""/>	
	<in_process methods="run"/>
	<transitions>
	<transition name="run_to_enemy" methods="eat_bullets">
		<condition function="near_the_bullets"/>
	</transition>
	</transitions>
</state>

Но XML очень не удобен для программирования. Покажем, как это описать с помощью DSL-языка.

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

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

Выводы

Все рассмотренные DSL:

  1. Небольшие и не требуют изучения. Это справедливо и в общем: язык предметной области с большим порогом входа — плохой.
  2. Позволяют оперировать терминами предметной области, без деталей программной реализации. Говорят ЧТО делать, а не КАК.
  3. Избавляют специалиста от необходимости получать высокую квалификацию в программировании.

DSL применяется, когда необходимо записать достаточно сложную логику и избавить специалиста в определённом домене от необходимости изучать программирование, а программиста — разбираться в предмете. Обратно, если для реализации задачи не нужно обладать квалификацией помимо собственно программирования, DSL вам не нужен.

Вторая статья будет посвящена графическим языкам программирования, последующие — способам реализовать DSL и применениям их в разных, иногда неожиданных областях.

LinkedIn

92 комментария

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

Класна стаття, пишіть ще!
Але, будь ласка, зробіть щось з формулою для матіндукції, бо то не є добре...

Спасибо за комментарий. Что с формулой не так?

— не дуже зрозуміло, як інтерпретувати вираз при n = 1;
— в формулу десь повинна входити база індукції;

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

Ирония мироздания в том, что многие скриптовые языки ведут свою родословную как раз из DSL. Однако, поднявшись в процессе роста до полноценных языков, становятся непонятными для непосвящённых. Тот же PHP или lua.

Часто язык является не полным по Тьюрингу, то есть написать любую программу с его помощью нельзя.

Хах, есть языки, полные по Тьюрингу, но любую программу на них всё равно не напишешь. Ибо произвол, беспредел, неравенсто, искуственные бюрократические ограничения и выдумывание анальных кар по ходу пьесы. См. Apple, AppStore, ObjC, Swift. В этом случае тоже позарез бывают нужны обходные манёвры, в том числе и DSL.

но, как правило, проблема в том, что кроссплатформа работает одинаково плохо на всех устройствах

Резко не соглашусь. Это как раз та история, которая верна в 99% случаев, но при этом оставшиеся прецеденты ни в коем случае нельзя сбрасывать со счетов, поддавшись внезапному порыву редукционизма. Посмотрите не на какой-нибудь Unity, а на Unreal Engine. Тоже, кстати, включает в себя весьма успешный DSL.

Обратно, если для реализации задачи не нужно обладать квалификацией помимо собственно программирования, DSL вам не нужен

Не вполне соглашусь. DSL иногда нужны даже одиночным программерам. Тупо ради сохранения сил на длинной дистанции. Однако, в подобном раскладе внешние DSL не нужны, равно как и DSL, заточенные на простоту освоения. За глаза хватит внутренних «диалектов», например на основе метапрограммирования.

Спасибо за статтю.
Относительно Java:
Можно написать для серверов легко читаемый код:

Server serverSex =       new ServerSex(10);
serverSex.addStrategy(new Fibonacci(10, EUR),
                                    new Fibonacci(10, USD) );
new Thread(serverSex).run();

А можно вовсе параметризировать и парсить в класе:

new Thread(new Server (“server:Box”,
			     “count:10”,
			     “Strategy:Fibonacci;10;USD”,
			     “Strategy:Fibonacci;10;EUR”
)).run();

Легко ошибиться и мало читаемо для людей, которые не знают java

Даже в паре строчек кода просто вызывающих api много шума навязанных синтаксисом языка со слабо развитой системов типов(Java). Данный же пример DSL выше из сравнения вполне валидный и реализуемый на функциональном языке(Scala, F#) без применения парсеров , поэтому о DSL на Java или удобстве читаемости таких вещей обычно принято молчать.
Немного оффтопа в тему читаемость императивных языков. Если речь пойдет о реализации самих методов или про написание алгоритмов — любой функциональный язык почти наверняка будет куда более читаeмый, лаконичный и понимаемый за счет декларативности чем Java, где все на сайд эффектах(сравните реализацию какого-нибудь merge sort на функциональном и императивном языке) — хер поймешь, что там происходит без покрытия тестами.

Годнота на ДОУ! Спасибо!

Владимир, спасибо за статью. Отличное начинание, надеюсь на доу будет больше подобных статей а не бесконечные «как уехать за бугор». Можете в следующей статье более подробно описать средства для быстрого создания dsl? flex/bison/yacc и иже с ним.

Могу и в Одессу приехать с докладом. Вот с этим. Флекс и Дайсон не актуальны. Стандарт antlr www.slideshare.net/vkozhaev/antlr4-in-depth

К сожалению моя компания навряд ли проспонсирует эту идею. Масштабы еще не те.

Неужели аренда зала и приятная компания для вас очень дорого?

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

Не попробуешь — точно не выйдет

Без проблем, зовите. Уже делал такой доклад и хорошо в xtext разбираюсь

Если вы в юбисофт (или где вы там работаете) договоритесь, будет хорошо. Зал для выступления и возможно билеты на транспорт

Норм начало.

Годная статья. я видел попытку сделать DSL из Java c помощью fluent interface

Так для простых DSL зачастую именно так и поступают. Библиотеки для mock’ов под юнит тесты (чем не DSL?) сплошь и рядом такое используют

Спасибо за статью! Уместно было бы упомянуть SQL: более классический и успешно живущий пример DSL придумать трудно.

Владимир — отличная вводная статья, и тема однозначно интересная!

Ещё лет 8-10 назад в индустрии была волна интереса к так называемым software factories, которые по сути DSL + богатый инструментарий создания прикладных приложений вокруг этих DSL. Но на практике, к сожалению, всё ограничилось максимум продвинутым scaffolding, что тоже результат, но явно не тот, на который расчитывали авторы концепции.

И где скачать этот универсальный DSL?

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

Витя, dsl писать надо. Каждый раз новый под задачу

Ну дык. Это уже пишется 100 лет в обед.

поскольку DSL это домейн specific, то говорить о, или ожидать «универсальный» не стоит

Питон с numpy и подобным тоже DSL. В итоге все языки программинга DSL, только каждый для своей области.
Или беру OpenCV и получаю DSL.

Ну нет же.
OpenCV может быть бек-ендом для DSL типа

Recognize cat in image cats.jpg, give coordinates as x1, y1 - x2, y2

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

Приходиться сначала строить модели, а потом их юзать уже.

Да, пардон, предполагается, что настроенная модель распознавания котиков уже есть. Хотя, в целом, не спорю — конечно, я излишне «очеловечил» свой пример.

Ну так в питоне почти так и юзается.

Увы, как оно юзается на Питоне, я не видел — возможно, там уже и напилили некое подобие DSL сверху байндингов к OpenCV. Но вот C++ интерфейс совершенно точно очень далёк от того, что можно было бы назвать DSL :)

Так и юзается. Почти DSL, но требуется знание Питона, как им писать. Примеров в инете для такого юзания море.
Но сложность в том, что помимо модели требуется еще куча разной обработки. Да, ее можно автоматизировать, но считаться тогда будет ну очень очень долго (будет внутрях решать кучу оптимизационных задач).

С++ интерфейс для других целей, а не просто влоб вызвать 3 функции в твоем стиле выше.

И да лет через 10 думаю появятся продукты, что будут работать в стиле, как ты хочешь.

Ну так в питоне почти так и юзается.

В DSL не менее существенно, кроме того, что он может, то, чего он не может (намеренно исключено).

И где скачать этот универсальный DSL?

Так это же ж си/си++ )) на нём на сегодняшний день практически вся существующая база написана ))

А что-то в этом есть... С точки зрения «аппаратчиков» даже ассемблер — DSL для юзеров, не умеющих в железо :)

[x] универсальный DSL
шутка года, например :)

Угу. 15 лет назад также про UML диаграмы говорили. Чегото не пошло. Забыли про них.

UML—диаграммы это всего лишь один DSL из счётного множества возможных. Притом довольно-таки квадратно-гнездовой и неадаптивный. Провал UML абсолютно ничего не говорит о судьбе DSL вообще. Они как были живы, так и живут в нишевых отраслях. Как раньше, так и сейчас, без растеризаторов postscript встанет колом вся полиграфическая индустрия, без SAP/ABAP — бизнес, а без Simulink и LabVIEW — огромное количество инженерных и машиностроительных задач.

Спасибо за статью.

Можно, конечно, использовать кроссплатформенные средства. Такие как Unity, или Haxe, но, как правило, проблема в том, что кроссплатформа работает одинаково плохо на всех устройствах. То есть хотелось бы сделать так, чтобы разрабатывать заново нужно было только специфические для конкретной платформы вещи, оставив логику без изменений.

Хе-хе, рад, что упомянул Haxe. Но Haxe как раз позволяет писать логику один раз и исполнять ее без изменений везде, разделяя ее с платформозависимыми вещами. Ну и, не совсем корректно ставить его на одну полку с Unity, потому что юнити — движок для игр, а Haxe — язык и тулкит с компилятором.
Кстати, у Haxe есть признаки FP (типа паттерн матчинга, ADT), так что на нем довольно прикольно писать всякие DSL. А еще, при помощи мощных макросов, которые дают доступ к AST и кодогенерации, можно добавлять свой синтаксис прямо в Haxe.

Haxe хорошая штука, но работы с ним мало и плохо оплачивается. Поэтому увы...

Это смотря, что продаешь. Если продукт, то язык, на котором он написан не имеет особого значения. Язык будет просто инструментом, который облегчает жизнь разработчику.

Чем DSL отличается от использования какой-нибудь специфичной под задачу библиотеки?

dsl это высокоуровневый api он ортогонален библиотекам

Тем, что язык заточен под задачу и по цели, и по ограничениям.
Библиотека же неспособна выставить такое ограничение для кода, который её использует.

Выводы
Все рассмотренные DSL:

Выводы:
Статьи на ДОУ никто не читает, поэтому можно делать те выводы, которые хочет автор :)

Небольшие и не требуют изучения. Это справедливо и в общем: язык предметной области с большим порогом входа — плохой.

В общем случае DSL требуют изучения и чем больше функционала они скрывают, тем больше обучения требуют.

Позволяют оперировать терминами предметной области, без деталей программной реализации. Говорят ЧТО делать, а не КАК.

Это называется декларативный подход. К слову DSL вполне могут быть императивными, что быет им гибкость (например система сборки gradle).

Избавляют специалиста от необходимости получать высокую квалификацию в программировании.

Древняя манца манагеров. Тут самый яркий пример несостоятельности идеии — это BPM-системы, хотели чтобы менеджер сам делал флоу, а на практике нанимаем специального инженера (или группу), который будет месяц менять 1 флоу, а если что-то сложное, то и доп разработку заказывать прийдется.

Примеры в статье — это не про DSL, а про уменьшение видемого текста, что не всега хорошо.
С тем же трейдингом вы просто заменили конфиг через создание объектов, на текстовый конфиг, при том не консистентный: Hilbert и Ichimoku имеют одну сигнатуру, MovingAverage — другую. Что значат числа в вашем конфиге вообще не понятно (в случае с джава кодом, понятности добавляет ИДЕ). Снова же в реальном трейдинге у вас будут 10-ки параметров.
В примере про «конечный автомат», так вообще нет _нового_ ДСЛ, а просто убрали из ХМЛ некоторые конструкции. Текста меньше, но вот обработать вашу «программу» автоматизировано будет сложнее, ибо будет завязка на АПИ __вашего__ парсера.

Статьи на ДОУ никто не читает, поэтому можно делать те выводы, которые хочет автор :)

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

В общем случае DSL требуют изучения и чем больше функционала они скрывают, тем больше обучения требуют.

Специалисту не особо надо учить. Возьмём например автолисп. Чертёжнику с опытом особо изучать не нужно.

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

Ну... это какой-то ужас-ужас в плане конструкции DSL

С тем же трейдингом вы просто заменили конфиг через создание объектов, на текстовый конфиг, при том не консистентный: Hilbert и Ichimoku имеют одну сигнатуру, MovingAverage — другую. Что значат числа в вашем конфиге вообще не понятно (в случае с джава кодом, понятности добавляет ИДЕ). Снова же в реальном трейдинге у вас будут 10-ки параметров.

Возможно я переработаю это для книги.

В примере про «конечный автомат», так вообще нет _нового_ ДСЛ, а просто убрали из ХМЛ некоторые конструкции. Текста меньше, но вот обработать вашу «программу» автоматизировано будет сложнее, ибо будет завязка на АПИ __вашего__ парсера.

Не будет, код транслируется в XML

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

Вы поговорите все-таки с вашим научруком, часть предисловия и статья — это разные вещи :)
Для части предесловия в нуачнопопулярной книжке нормально.

Не будет, код транслируется в XML

Тогда точно писец. В чем была необходимость ДСЛ? Если были проблемы с наглядностью, то проще нарисовать картинку (по ХМЛ), проблемы ввода — формочка для базовых пользователей, для продвинутых ХМЛ вполне сойдет (ДСЛность сохраняется)

Тогда точно писец. В чем была необходимость ДСЛ? Если были проблемы с наглядностью, то проще нарисовать картинку (по ХМЛ)

Будет в последующих статьях. Ждите-ждите

Возьмём например автолисп. Чертёжнику с опытом особо изучать не нужно.

Я, конечно, ненастоящий сварщик отнюдь не чертёжник с опытом, но напомнило историю студенческих времён :)

В программирование на императивных языках я тогда уже умел вполне хорошо. Но аутсорс в конце 90х находился в зачаточном состоянии, и студенту без какого-либо опыта попасть на работу было практически нереально. А деньги были нужны, поэтому подрядился в проектный институт переносить чертежи с бумаги в автокад. Довольно скоро выяснилось, что в работе встречается ряд типовых операций из серии «выделить на чертеже десять линий и сделать их жирными пунктирными». И, уж не знаю откуда, я в те времена краем уха прослышал, что есть такая штука, как autolisp — что какбы намекало на возможность запилить макросы под всю эту рутину.

Так вот — собственно, осилить чертёжные операции было несложно, тем более, что удалось найти автокадовский мануал. Сложно было осилить сам lisp, который изобрёл не иначе как «сам Сатана в периоде глубокой депрессии» ©. Так это мне, программисту, хоть и «системщику». А как бы пришлось сломать себе мозг чертёжнику — мне даже страшно себе представить.

P.S. Предвосхищая вопросы вида «а вы что, в универе ничего, кроме императивных языков, не учили?» сразу отвечу: нет, не учили — у нас была специализация с уклоном в системотехнику, системное программирование и криптографию. На первом курсе Паскаль, а потом — C, C++, Ассемблер.

Я как-то таки несколько сомневаюсь что автолист следует считать и рассматривать как «неимперативно функциональный» по крайней мере я помню в самом институте у меня с ним проблем и вопросов не возникло ну скобочки ну и что?

Дело было 20 лет назад, поэтому в деталях затрудняюсь вспомнить. Но что точно осталось в памяти, что программирование на этой штуке радикально отличалось от C++ и Паскаля именно в плане подхода, а не только синтаксиса. Возможно, потому, что в Лиспе «всё — это список»

Мне повезло. Я случайно зашёл в какой-то книжный магазин как сейчас помню вроде «заводской» где-то в районе ж/д вокзала хотя могу и ошибаться но там встретился талмуд по автокаду 10 толстенная такая книга видимо «заводской полиграфии» причём к.м.к. даже свёрстана в самом же ж автокаде и там было всё нет там было ПРОСТО ВСЁ!!! ))) причём вот именно как-то так написано не как «для тупых за 21 день» а именно конкретно «инженер инженеру» крайне удачно таки да тупо повезло.

ЗЫ: надо будет как-нибудь заехать и собрать и сложить и наверное может потом переправить морем всю бумажную библиотеку буду потом когда-нибудь внукам показывать ))

В общем случае DSL требуют изучения и чем больше функционала они скрывают, тем больше обучения требуют.

Чим більше функціональності приховано, тим більш загальний буде DSL та тим простішим він буде для вивчення. Та зовсім не факт, що ядро, яке буде опрацьовувати цей DSL, буде сильно складнішим. DSL мусить описувати в найкращий спосіб процес, а не особливості реалізації. Прийдеться перейти на більш високий рівень абстракцій, що тільки позитивно скажеться на архітектурі.

Чим більше функціональності приховано, тим більш загальний буде DSL та тим простішим він буде для вивчення.

Ок, «скрывает» не правильное слово, «содержит» более подходящее.

DSL мусить описувати в найкращий спосіб процес,

Проблема в том что для сложных процессов получаются или сложные ДСЛ, или бесполезные. Думаю по этому автор для своих примеров взял простые конфиги, а не попытался описать хотя бы простую арбитражную стратегию (там где стейт-машина больше чем 2-3 состояния)

для сложных процессов получаются или сложные ДСЛ, или бесполезные.

Для сложных процессов можно применять графические DSL. В следующей статье о них будет

Для сложных процессов можно применять графические DSL

То-то я смотрю, это решило все проблемы с БПМ-системами. А как УМЛ помогает в разработке-то, повсеместно используется :)

UML не эргономичен и в этом его проблема. Я буду об этом писать

Проблема БПМ-систем не в візуалізації, а неправильній декомпозиції та реалізації.

Проблема БПМ-систем не в візуалізації, а неправильній декомпозиції та реалізації.

технологии идеальны, а люди м...аки :)

Если уж речь зашла про BPM и DSL, давай тогда вспомним про BPMN :)

Для сложных процессов можно применять графические DSL. В следующей статье о них будет

Жду с нетерпением (без сарказма).
Те же Microsoft, хоть их и принято ругать на все лады, одно время добавили в Visual Studio довольно неплохой графический инструментарий для DSL. Но, увы — не взлетело :(

одно время добавили в Visual Studio довольно неплохой графический инструментарий для DSL.

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

ЗЫ: там ещё фишка вот в чём копроративная вертикаль предполагает инструменты передачи информации читай «спецификации» а «самая детальная спецификация» это и есть код и чем выше по уровням копроративной вертикали тем эта «спецификация» всё «абстрактнее» и термины чисто технически меняются и идея якобы «условный топ менеджмент или второе звено» будет сидеть и «рисовать формочки в графическом инструментарии» получая при этом своих $250 в час (читай расходуя копроративного расхода) это мягко говоря не работает просто потому что для этого есть специально обученные люди от $25 в час а вот им-то уже все эти «графические инструментарии» нафиг не сдались просто потому что. А для передачи информации по вертикали эти «инструменты» снова не пригодились тут вон один только UML и тот вон ни дня не пройдёт как кто-то напишет мол «уже умер» ))

Проблема в том что для сложных процессов получаются или сложные ДСЛ, или бесполезные.

Якщо процес складний, значить ви погано зробили декомпозицію.

хотя бы простую арбитражную стратегию (там где стейт-машина больше чем 2-3 состояния)

Та немає різниці скільки станів, хоч триста. Процес переходу між ними однаковий має бути. Однаковий за процедурою/методологією. Приведу приклад документообігу. Є документ в певному стані. В залежності від ситуації документ може переходити до 10 інших станів. Запитання, яка методологія мусить тут бути?

Вхід => Оцінка поточного стану => Прийняття рішення => Перехід в інший стан => Вихід
Ця процедура може обслуговувати хоч тисячу станів, немає різниці. Основна задача тепер — побудувати правильну реалізацію пункту «Оцінка поточного стану», це «найскладніша» (насправді ні) частина цієї системи. Її теж можна описати приблизно наступним чином

Вхід => Збір даних про стан системи => Скорінг => Вихід

Теж елементарно, правда? Далі можна ще довго продовжувати, заглиблюючись в надра процесів, але вже зараз можна сказати одне — методологія примітивна та може бути легко описаною DSL. Простим.

Вхід => Збір даних про стан системи => Скорінг => Вихід

Теж елементарно, правда?

Можно проще: Вход — Выполнение работы — Выход

Та немає різниці скільки станів, хоч триста.

И каждому из 300-т надо свои параметры. И по факту у вас получается 300 маленьких ДСЛей.

В тоерии ДСЛи очень классная штука, вот только почему-то удачных примеров очень мало и по всем видутся споры об их удачности.
Может у вас есть примеры простых ДСЛей, которые покрывают обширный функционал. Потому что ТС не смог привести таких примеров. Первый пример — удачи нарисовать синусоид, второй — просто конфиг (который стал менее четабельным, за счет отсутствие поддержки в ИДЕ), 3 — из ХМЛ пострипал теги.

И каждому из 300-т надо свои параметры. И по факту у вас получается 300 маленьких ДСЛей.

Неправильно, ДСЛ буде лише один. Тому що процес не міняється, а ДСЛ описує саме його, не дані!

В тоерии ДСЛи очень классная штука, вот только почему-то удачных примеров очень мало и по всем видутся споры об их удачности.

На практиці він теж крутий. Просто для його успішної реалізації потрібно міняти мислення, що дається не всім розробникам.

Может у вас есть примеры простых ДСЛей, которые покрывают обширный функционал

Задача ДСЛ не покривати обширну функціональність, а вирішувати специфічну задачу з мінімальними витратами на зміни коду. Будь-яка темплейт система — приклад успішної реалізації.

Так графы фильтров, один из успешных вариантов. gstreamer тот же.
Но это всё частные случаи, автор же на какой-то супер-пупер универсальный намекал.
Конечные автоматы — другой частный успешный случай.

Древняя манца манагеров. Тут самый яркий пример несостоятельности идеии — это BPM-системы, хотели чтобы менеджер сам делал флоу, а на практике нанимаем специального инженера (или группу), который будет месяц менять 1 флоу, а если что-то сложное, то и доп разработку заказывать прийдется.

В точку. Я сегодня с утра клиенту писал именно этот пример про иллюзии BPM!

Это потому, что ваши инструменты не очень. Напиши мне — за поговорить денег не беру.

Використовую DSL багато років. Можу сказати тільки одне — це найкраще, що є в програмуванні. Це єдиний шлях зменшити кількість помилок в коді та досягти ефективності в роботі команди.

Недолік тільки один — швидкість може страждати суттєво, бо з’являється ще одна надбудова. Полікувати можна шляхом кодогенерації та компіляції, але не у всіх мовах таке можливо.

Непоганий початок, чекаємо продовження.

Побічне питання — Jetbrains мають якусь систему, яка називається MPS — www.jetbrains.com/mps
Хтось щупав? як воно?

youtu.be/7JTPogrzYwE?t=467

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

Я пошел чтоб получить клиентов. И они появились

У них есть еще Nitra, в своем время юзал.
Довольно специфичный интрумент, но свою нишу имеет.
И это .NET а не Java.

А вот ось вам контрагурмент про DSL:
locklessinc.com/...​articles/why_lisp_failed

So what is the problem with creating domain-specific languages as a problem solving technique? The results are very efficient. However, the process causes Balkanization. It results in many sub-languages all slightly different. This is the true reason why Lisp code is unreadable to others. In most other languages it is relatively simple to work out what a given line of code does. Lisp, with its extreme expressibility, causes problems as a given symbol could be a variable, function or operator, and a large amount of code may need to be read to find out which.

Если ты заметил, речь идёт о внешних dsl в то время как lisp создан для внутренних. С другой стороны, dsl это не решение а инструмент для решения проблем

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

Это или плохие dsl-и, или не dsl-и вообще. Хороший dsl учить не надо

Тогда идеальный DSL — это естественный человеческий язык. Вот только пока никто не смог естественный текст в программу автоматически преобразовать и еще очень долго не сможет.

Тогда идеальный DSL — это естественный человеческий язык.

Есть теория что не идеальный...

en.wikipedia.org/...​iki/Linguistic_relativity

Пока что худший язык, придуманный человечеством — это AppleScript. С огромным отрывом от всего живого. А создавался он именно с целью быть похожим на английский :)

Это вы, наверное, COBOL не видели :)
А ведь тоже задумывался как язык для менеджеров и бизнес-аналитиков

больше на вбскрипт похож)

Тоже еще тот отстой, но со своими целями и задачами справляется, околобухгалтерам нравится :)

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

Ну то з якого боку подивитись. Природні мови ми вчимо все життя і то часто результат буває так собі. Я би сказав, що хороший DSL, то щось типу Turtle graphics: три з половиною команди, які можна вважати вивченими як тільки користувач їх побачив + для створення простеньких симетричних малюнків важко придумати більш зручний підхід.

Идеальный чтоб писать? Сомневаюсь. Чтоб читать? Да вот, пожалуйста. Писали уже и далеко не раз.

Все таки цитата відносться власне до lisp-а, який з його мінімальним синтаксисом дозволяє вивертати і писати DSL на lisp-і.
Аналогічно поводяться стекові мови, типу forth — кожна програмна система це і є DSL, написаний на forth-і.

Але наведені приклади, власне, не є кодом ні на lisp-і, ні на forth-і, а є списком певних предикатів та описів дії.

Подписаться на комментарии