Не точно выразился, имел в виду встраивание SQL в чистом виде. LINQ — уже не совсем SQL, а какая-то вариация. Например, в следующей статье нам понадобятся выражения для создания таблиц, а в LINQ их как-раз нет.
Кстати, есть примеры DSL, которые встраиваются в другие языки без изменений. Например, OCL встроен в Acceleo, QVTo, ATL. Или XPath встраивается в XSLT, XSD. Арифметические выражения в разных языках примерно одинаковые. Такие микроDSL очень клёвые тем, что позволяют при создании нового языка не изобретать уже существующие вещи.
Это наверное обратный подход тому, который описал выше Throwable. Мы не строим DSL на основе языка программирования общего назначения. А наоборот, создаём новый язык в который встраиваем существующий микроDSL.
Интересная штука, получается комбинированный редактор. Кстати, на что-то такое тут уже была ссылка (см. слайд на котором вместо switch/case в коде таблица).
EMFText обмен объектов местами не заметит: модель AST создаст с нуля, а о 2-ой модели со скрытыми данными он ничего не знает. Но в разрешателе ссылок можно реализовать какую угодно логику. В статье выше есть пример — класс FeatureTypeReferenceResolver. Метод resolve разрешает ссылку type у некоторого объекта класса Feature:
Для этого мы сначала от Feature (который передается в параметре container) переходим к EntityModel:
EntityModel model = (EntityModel) EcoreUtil.getRootContainer(container);
Потом находим в EntityModel некоторый Type с нужным идентификатором.
Но эта логика может быть совершенно другой. Во-первых, можем искать объект (на который хотим сослаться) в другой модели. Во-вторых, можем сделать что-то такое… Неважно какой идентификатор передали в параметре identifier. Вместо него смотрим порядковый номер текущего объекта класса Feature в AST. И потом ищем во второй модели нужный объект уже не по идентификатору, а с таким же порядковым номером.
Я не рекламирую EMFText, на самом деле в нём хватает косяков :) Но в Xtext, я думаю, это должно делаться аналогично.
Ещё можно разрешать ссылки по контексту… Искать родительский объект с нужным ID, а потом дочерний нужного типа с определенным порядковым номером. Или искать не родительский, а предыдущий или последующий объект.
Или всё-таки сохранять эти скрытые данные в исходном коде, но скрывать средствами редактора, хотя я такого никогда не делал.
А что это за данные, если не секрет? Немного странно, что их можно редактировать в окне свойств, но нельзя в коде :)
Спасибо за комментарий, про Xtext я написал маловато. У него конечно больше отличий от EMFText. Для него есть язык описания выражений Xbase с трансляцией в Java-код. Xbase используется в Xtend, который вы упомянули. Также он используется в Xcore, о котором я писал немного раньше. И Xbase может использоваться в любом DSL, который транслируется в Java.
Вообще, если планируется создавать DSL на основе Java, то Xtext выглядит гораздо предпочтительней, чем EMFText. Но EMFText, на мой взгляд, проще и легче.
Я согласен, что DSL внутри языков сейчас очень популярны. Но не все DSL можно или нужно встраивать в какой-то язык программирования :) Например, SQL. В следующей статье я опишу парсер/генератор/редактор SQL на основе EMFText. А потом опишу транслятор из Anchor-моделей в SQL-код. Это как-раз пример задачи, в которой не нужно делать DSL внутри языка программирования.
XSLT отличная штука, но писать на нём сложные преобразования моделей не очень удобно. В одной из следующих статей я напишу про QVTo — это аналог XSLT для MOF-моделей. Кстати про отображение MOF-метамоделей в XSD-метамодели я тоже планирую статью. Если нужно парсить или генерить XML, то можно конечно делать что-то подобное, но можно проще.
Я бы попробовал разбить модель на две: 1) модель со скрытыми данными и 2) модель, которая генерится из исходного кода. Каждый раз при парсинге восстанавливал бы ссылки из 2-ой модели в 1-ую.
Да, судя по всему, при любом изменении исходного кода он полностью парсится и создаётся новая модель.
Тут люди спрашивали про инкрементальный парсинг, но из коробки этого нет.
Я в основном пользовался парсером и кодогенератором, чтобы делать транслятор с одного языка на другой:
1) парсим код на языке 1 в AST
2) преобразуем это AST в AST для языка 2
3) преобразуем второе AST в код на языке 2
Редактор использовал только для отладки (чтобы посмотреть правильно ли работает парсер и т.п.).
А зачем отслеживать изменения в модели? Можно сделать постобработчик, который принимает новую модель после парсинга и что-то с ней делает.
Я не совсем понял вопрос :) Выгода от EMF или EMFText? Про смысл модельно-ориентированной разработки я планирую отдельную статью — в каких ситуациях стоит всё это использовать, в каких — нет.
Сокращение вероятности ошибок в коде, потому что он генерится автоматически, уменьшена роль человеческого фактора.
Упрощение сопровождения ПО. Например, через 50 лет (когда вместо Java будет какой-то более модный язык) мы просто снова нажмём кнопку «сгенерировать исходный код» и получим код уже на этом новом языке, не нужно будет переписывать тонны строк кода.
Увеличение повторного использования. В этой статье мы использовали метамодель для генерации Java API и древовидного редактора, в этой статье эта же самая метамодель используется для создания графического редактора. Если мы захотим сделать DSL для таких моделей, то снова повторно используем ту же самую метамодель.
Кросплатформенность. Можно генерить код на любом языке для любой платформы.
Спасибо! В общих чертах представляю, но не использовал. Мы делаем идейно что-то подобное, но с другим назначением, и на входе немного другая модель, на выходе генерируется немного другой код.
Приходится часто сталкиваться со скепсисом. Для большинства людей EMFText, Xtext, QVTo и т.п. — это «какие-то сомнительные плагины, выдранные из не очень хорошей среды разработки Eclipse». И вообще, людям непонятно зачем нужны ещё какие-то языки, если то же самое можно написать на Java.
Очень клево! Казалось бы это совершенно естественное направление развития подобных программ, но лично у меня почему-то онтологии всегда ассоциировались с поисковыми системами или интеграционными шинами.
Интересная идея! Я думаю, чтобы это было возможно нужно проанализировать много игр, найти в них какие-то общие вещи. В итоге получится какая-то игровая онтология. А потом машина будет по онтологии задавать наводящие вопросы человеку, чтобы понять что это именно за игра.
Например, во всех играх есть игроки, их может быть определенное количество. Они могут играть разные роли. В игре могут быть вспомогательные объекты (доска, фишки, фигуры, карты, кубики). Игроки в определенной последовательности что-то делают. Делают с объектами (кидают кубик) или без объектов (загадывают число, говорят что-то другим игрокам).
В каждой игре должна быть какая-то целевая функция, возможные окончания (выигрыш, проигрыш, ничья) или промежуточные этапы.
Машина может либо узнавать по вопросам игры, которые она знает. Либо может узнавать у человека новые игры.
Есть готовый софт для создания разных типовых игр www.gambit-project.org
Есть теория, та же теория игр.
Пример кода в видео выглядит гораздо сложнее кода на обычных ЯП…
каждая инструкция однозначно отражает намерение разработчика, ее написавшего
Слово «есть» можно интерпретировать как прием пищи. Не факт, что стоит разбивать термин «солнечная система». Стоит ли разбивать термин «атом водорода» тоже наверное зависит от ситуации… Т.е. язык получается не очень однозначный.
Чтобы такой язык был возможен, нужна онтология. Вообще, интересная идея использовать онтологии при программировании…
В следующей статье будет редактор Anchor-диаграмм. Потом транслятор Anchor-моделей в ER-модели. Потом, видимо, пример реализации какого-нибудь DSL (текстовая нотация для того же Anchor или SQL).
Есть Emfatic. Причем, в Epsilon целое семейство именно текстовых языков для разных задач.
Ещё есть EMFText и Xtext, которые позволяют создавать DSL, для Ecore-моделей. Я как-раз в одной из ближайших статей планирую про них написать. Пока не решил: опишу текстовую нотацию либо для Anchor, либо для SQL.
Статья не претендует на обзор по методам моделирования данных. Я мог бы для примера взять модель типа «мужчины», «женщины» и отношение «родитель-потомок», типа такой. Но решил сделать более полезный в реальной жизни пример.
Статья всё-таки посвящена разработке, управляемой моделями, и моделирование данных затрагивает очень вскользь. Ну, надеюсь, что это «вскользь» будет кому-то полезным… Наверняка мало кто расшифрует ORM как Object-role modeling, а не как Object-relational mapping. Наверняка не многие ли слышали об Anchor. Думаю, что мало кто использует 6НФ. Я только немного приподнял эти темы из небытия…
Согласен, но это не научная статья :) Поэтому я не уделял особого внимания источникам, проблематике.
Реляционная алгебра и вообще моделирование данных имеют очень опосредованное отношение к основной теме статей (разработка, управляемая моделями). Поэтому я их затронул ровно на столько, чтобы было вообще понятно что такое Anchor и зачем он может быть нужен. Я ориентировался на человека, который возможно никогда не занимался моделированием данных. Плюсы и минусы реляционной алгебры для него явно лишние. Тем более, я не утверждаю, что какие-то подходы лучше или хуже. Просто говорю, что есть разные подходы к моделированию. И есть инструмент, который позволяет реализовывать эти языки моделирования.
Но замечание конечно принимается. Если затрагиваешь какую-то тему, то будь добр, раскрыть её нормально.
Кстати, есть примеры DSL, которые встраиваются в другие языки без изменений. Например, OCL встроен в Acceleo, QVTo, ATL. Или XPath встраивается в XSLT, XSD. Арифметические выражения в разных языках примерно одинаковые. Такие микроDSL очень клёвые тем, что позволяют при создании нового языка не изобретать уже существующие вещи.
Это наверное обратный подход тому, который описал выше Throwable. Мы не строим DSL на основе языка программирования общего назначения. А наоборот, создаём новый язык в который встраиваем существующий микроDSL.
EMFText обмен объектов местами не заметит: модель AST создаст с нуля, а о 2-ой модели со скрытыми данными он ничего не знает. Но в разрешателе ссылок можно реализовать какую угодно логику. В статье выше есть пример — класс FeatureTypeReferenceResolver. Метод resolve разрешает ссылку type у некоторого объекта класса Feature:
Для этого мы сначала от Feature (который передается в параметре container) переходим к EntityModel:
Потом находим в EntityModel некоторый Type с нужным идентификатором.
Но эта логика может быть совершенно другой. Во-первых, можем искать объект (на который хотим сослаться) в другой модели. Во-вторых, можем сделать что-то такое… Неважно какой идентификатор передали в параметре identifier. Вместо него смотрим порядковый номер текущего объекта класса Feature в AST. И потом ищем во второй модели нужный объект уже не по идентификатору, а с таким же порядковым номером.
Я не рекламирую EMFText, на самом деле в нём хватает косяков :) Но в Xtext, я думаю, это должно делаться аналогично.
Или всё-таки сохранять эти скрытые данные в исходном коде, но скрывать средствами редактора, хотя я такого никогда не делал.
А что это за данные, если не секрет? Немного странно, что их можно редактировать в окне свойств, но нельзя в коде :)
Вообще, если планируется создавать DSL на основе Java, то Xtext выглядит гораздо предпочтительней, чем EMFText. Но EMFText, на мой взгляд, проще и легче.
Я согласен, что DSL внутри языков сейчас очень популярны. Но не все DSL можно или нужно встраивать в какой-то язык программирования :) Например, SQL. В следующей статье я опишу парсер/генератор/редактор SQL на основе EMFText. А потом опишу транслятор из Anchor-моделей в SQL-код. Это как-раз пример задачи, в которой не нужно делать DSL внутри языка программирования.
XSLT отличная штука, но писать на нём сложные преобразования моделей не очень удобно. В одной из следующих статей я напишу про QVTo — это аналог XSLT для MOF-моделей. Кстати про отображение MOF-метамоделей в XSD-метамодели я тоже планирую статью. Если нужно парсить или генерить XML, то можно конечно делать что-то подобное, но можно проще.
Я бы попробовал разбить модель на две: 1) модель со скрытыми данными и 2) модель, которая генерится из исходного кода. Каждый раз при парсинге восстанавливал бы ссылки из 2-ой модели в 1-ую.
Тут люди спрашивали про инкрементальный парсинг, но из коробки этого нет.
Я в основном пользовался парсером и кодогенератором, чтобы делать транслятор с одного языка на другой:
1) парсим код на языке 1 в AST
2) преобразуем это AST в AST для языка 2
3) преобразуем второе AST в код на языке 2
Редактор использовал только для отладки (чтобы посмотреть правильно ли работает парсер и т.п.).
А зачем отслеживать изменения в модели? Можно сделать постобработчик, который принимает новую модель после парсинга и что-то с ней делает.
Основная выгода от EMF — экономия времени на рутинном написании типового кода. Например, в одной из предыдущих статей мы описали модель в декларативном платформо-независимом виде:
Потратили на это не очень много времени. Затем нажали кнопку «сгенерировать исходный код» и получили целую кучу Java-классов, интерфейсов, фабрик со всякими геттерами, сеттерами и т.п.
Т.е. выгода:
Приходится часто сталкиваться со скепсисом. Для большинства людей EMFText, Xtext, QVTo и т.п. — это «какие-то сомнительные плагины, выдранные из не очень хорошей среды разработки Eclipse». И вообще, людям непонятно зачем нужны ещё какие-то языки, если то же самое можно написать на Java.
Мне этот метод нравится тем, что он очень простой. Для тех кто не хочет разбираться с Eclipse и т.п. запилил калькулятор в Excel
Интересная идея! Я думаю, чтобы это было возможно нужно проанализировать много игр, найти в них какие-то общие вещи. В итоге получится какая-то игровая онтология. А потом машина будет по онтологии задавать наводящие вопросы человеку, чтобы понять что это именно за игра.
Например, во всех играх есть игроки, их может быть определенное количество. Они могут играть разные роли. В игре могут быть вспомогательные объекты (доска, фишки, фигуры, карты, кубики). Игроки в определенной последовательности что-то делают. Делают с объектами (кидают кубик) или без объектов (загадывают число, говорят что-то другим игрокам).
В каждой игре должна быть какая-то целевая функция, возможные окончания (выигрыш, проигрыш, ничья) или промежуточные этапы.
Машина может либо узнавать по вопросам игры, которые она знает. Либо может узнавать у человека новые игры.
Есть готовый софт для создания разных типовых игр www.gambit-project.org
Есть теория, та же теория игр.
Вообще это тянет на кандидатскую диссертацию :)
Слово «есть» можно интерпретировать как прием пищи. Не факт, что стоит разбивать термин «солнечная система». Стоит ли разбивать термин «атом водорода» тоже наверное зависит от ситуации… Т.е. язык получается не очень однозначный.
Чтобы такой язык был возможен, нужна онтология. Вообще, интересная идея использовать онтологии при программировании…
Ещё есть EMFText и Xtext, которые позволяют создавать DSL, для Ecore-моделей. Я как-раз в одной из ближайших статей планирую про них написать. Пока не решил: опишу текстовую нотацию либо для Anchor, либо для SQL.
Статья всё-таки посвящена разработке, управляемой моделями, и моделирование данных затрагивает очень вскользь. Ну, надеюсь, что это «вскользь» будет кому-то полезным… Наверняка мало кто расшифрует ORM как Object-role modeling, а не как Object-relational mapping. Наверняка не многие ли слышали об Anchor. Думаю, что мало кто использует 6НФ. Я только немного приподнял эти темы из небытия…
Реляционная алгебра и вообще моделирование данных имеют очень опосредованное отношение к основной теме статей (разработка, управляемая моделями). Поэтому я их затронул ровно на столько, чтобы было вообще понятно что такое Anchor и зачем он может быть нужен. Я ориентировался на человека, который возможно никогда не занимался моделированием данных. Плюсы и минусы реляционной алгебры для него явно лишние. Тем более, я не утверждаю, что какие-то подходы лучше или хуже. Просто говорю, что есть разные подходы к моделированию. И есть инструмент, который позволяет реализовывать эти языки моделирования.
Но замечание конечно принимается. Если затрагиваешь какую-то тему, то будь добр, раскрыть её нормально.