Персональные инструменты
 

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011)/Стенограмма

Материал из CustisWiki

Перейти к: навигация, поиск
Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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

Меня зовут Максим Мазин, я работаю в компании JetBrains инженером в проекте YouTrack. YouTrack — это багтрекер, и самое увлекательное в YouTrack то, что он написан с помощью Language Record программирования. Что это такое? Это такая концепция, которая полагает, что при написании программ, первым делом вы создаете специальный предметно-ориентированный язык, а затем, на этом предметно-ориентированном языке, вы начинаете уже писать собственно код программы.


Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Смотрите — вот существуют универсальные языки программирования. При программировании при помощи языка Java, PHP или C# возникает проблема — у вас при программировании возникает огромное количество bullet plate (??? 01:15) -кода, т.е. такого кода, который будет повторяться из раза в раз, но не потому, что он делает какую-то содержательную работу, а просто для того, чтобы компилятор мог этот код скомпилировать. Писать скобочки круглые, точки, … ну и так далее.

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

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

В языке Java существует конструкция synchronized, которая не является какой-то конструкцией общего назначения, является специальной, предметно-ориентированной конструкцией, предназначенной для параллельного программирования.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Точно так же, в языке C++, существует перегрузка операторов. Вот, сравните. В нормальной ситуации, если бы у вас не было конструкции synchronized вам бы пришлось написать вот столько вот кода. Блок «finally» и блок получения блокировки, это все вот bullet-plate код, который не интересно писать постоянно. Вместо этого существует DSL-ная конструкция «synchronized», которая позволяет захватить блокировку и не беспокоится о том, что ее надо отпустить.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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


Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Это все очень хорошо, но как вы знаете, что в языке Java, начиная с пятой версии, появились read-write локи, и это означает для нас, что нам снова нужно писать код вот такого стиля, как показано слева:

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Т.е. надо блокировки захватывать, блокировки отпускать, … это все полностью нивелирует удобства.

Если бы можно было писать… самостоятельно расширять языки, нам бы удалось решить разные проблемы. Например, те конструкции, языковые расширения, которые есть, в языке Java, они позволяют вам решать определенный набор задач. Но мы в жизни сталкиваемся и с другими задачами. Например, если мы пишем веб-аппликейшн, то нам нужно работать с базами данных, писать веб-уровень, и так далее. Для этого DSLей нет, есть только фреймворк.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Точно также, если мы используем какую-нибудь концепцию вроде dependency injection, то нам тоже нужно для этого использовать фреймворки, и хуже того — использовать смеси языков, писать одновременно на Java, на XMLе, и все это не очень весело. И главное — нам ничего с этим не поделать, потому что создание языкового расширения грозит нам разными рисками.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Какие проблемы возникают при создании DSL и почему бы при возникновении какой-нибудь потребности не бросаться сразу создавать DSL?

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Вот например. Если у вас есть некоторые библиотеки и фреймворки, в нашем случае для Java, например Hibernate, Spring или Joda Time, то все они между собой совместимы, принципиально, на уровне компиляции. Т.е. вы можете одновременно использовать в вашем проекте компоненты и Hibernate и Spring, и ничего вам не может помешать. Но если у вас есть языковые надстройки, в виде каких-то макросов, или еще каких-нибудь техник, которые добавляют вам предметно-ориентированные конструкции в язык Java, то и эти надстройки созданы независимым образом, то все время существует риск, что эти надстройки будут с друг другом конфликтовать.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf
Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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

В тоже самое время, в друг к нам приходит другое языковое расширение, которое позволяет делать что-то полезное и в частности тоже делает интерполяцию строк. В Java же нет интерполяции строк, поэтому достаточно ожидаемо, что разные люди будут ее релизовывать в разных языковых расширениях. И допустим, синтаксис слегка отличается. Тогда при совместном использовании языковых расширений A и B, у вас мгновенно возникает неустранимая неоднозначность, как следует интерпретировать вот этот вот buzz.

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

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Другая проблема, которая мешает нам создавать DSLи. Допустим тем не менее, вопреки сложностями и проблемам с совместимостью разных расширений вы принимаете решение написать DSL. Пишите какой-нибудь препроцессор, натравливаете этот препроцессор на вашу программу вашими DSLными конструкциями, она компилирует и выдает какой-то код, байт-код например, или какой-то исполняемый код. Это все очень хорошо, но в наше время никто не пишет код, не используя IDE. Так не делают просто, потому что без использования IDE продуктивность разработчика драматически снижается. Поэтому в большинстве случаев, когда вы создадите такой DSL, будут ситуации, когда ваши разработчики, ваши коллеги, предпочтут использовать просто язык Java в Idea, просто язык C# вместе с ReSharperом, нежели брать ваше поделие, и что-то с помощью вашего поделия писать, потому что нет поддержки IDE.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Под поддержкой IDE понимается все возможности, которые современные IDE оказывают разработчику. Т.е. это подсветка синтаксиса естественно, подсветка ошибок до компиляции, рефакторинг, интеграция с Version Control-ами, все остальное.

И да, можно отметить, что само по себе создание языка это решенная математическая задача. Если у вас есть пример для представления синтаксиса, вы сможете создать компилятор. Но она, тем не менее, трудоемкая, даже если вы используете компилятор компиляторов.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Существуют очень много разных попыток сделать это, поддержать DSL в том или ином виде, тема очень горячая, тут наверное еще можно добавить Nemerle, и может быть еще OCaml, сейчас есть очень много разных средств, чтобы создавать DSLи. В рамках Eclipsa существует XText-фреймворк, который позволяет написать грамматику и получить что-то вроде DSLя c поддержкой IDE.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Но к счастью, в нашей компании JetBrains, была создана среда MPS.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

MPS означает meta-programming system, в основном предназначена для создания и расширения языков, причем такого расширения, что сразу после его создания появлялась поддержка IDE.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Попытки такие ранее предпринимались, и как правило такие попытки сводятся к редактированию диаграмм. Рисуется диаграмма, в некотором смысле… у меня ребенок программирует на свойствах в большей степени, вы рисуете диаграммы, у вас получаются картинки, далее эти картинки собираются, получается код.

Есть проблема — рисовать эти картинки неудобно — мышкой хватать, таскать, неудобно. У нас, у программистов, есть привычка писать код вручную.

Поэтому в MPSе реализована концепция проекционных редакторов.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

О чем речь? Вот у вас есть абстрактное синтаксическое дерево. Т.е. это то представление программы, которое получается, в любом случае получается, когда парсер распарсил программу. В то же время, у вас есть его проекция, во что-то вроде текста.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Для каждого узла этого синтаксического дерева есть соответствующая ему ячейка. Те из вас, кто знакомы с TeXом, должны примерно представлять, примерно похожие концепции. Точно также, для каждого элемента у вас есть ячейка, ячейки объединяются в еще более крупные ячейки и так далее.

При этом воздействие на эти ячейки, когда вы пишете в эти ячейки, или каким-то образом на них воздействуете, то сразу же, мгновенно влияет на эту деревяшку. При этом наша цель, как разработчиков MPS, сделать так, чтобы вы вообще не чувствовали, что вы работаете не с текстом, а с напрямую с деревяшкой. Здесь конечно проблема, но те из вас, кто пользуются IDEA, должны понимать, что когда вы редактируете текст в IDEA, Eclipse или еще где-то, вы тоже не редактируете текст — вы тайпаете что-то, что поглощается IDEA, и она это во что-то превращает. В случае Eclipse это в большей степени редактирование текста, в случае IDEA — это еще меньше редактирования текста.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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

Отрицательная сторона, состоит в том, что все-таки есть некоторое отличие от редактирования текста. В тоже самое время, (???) проблема. Дело в том, что привыкание… по нашему опыту, люди, которые начинают работать с MPSом, они привыкают к стилю программирования внутри MPSа, примерно в течении двух недель. Т.е. в течении этих двух недель они могут выдавать какую-то положительную обратную связь, о том, что им неудобно, непривычно, чем-то отличается от программирования в текстовом редакторе. Через две недели они привыкают и начинают работать с той же скоростью, как они работали ранее. Я надеюсь, что если вы попробуете скачать, и начнете пользоваться, то мы получим больший feedback, и мы сможем сделать проекционный редактор еще более похожим на текстовый редактор.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Идея такая. При создании языков вы выписываете мета-модель языков, его абстрактный синтаксис, задаете систему типов, описываете конкретный синтаксис, и автоматически получаете на выходе язык, вместе с компилятором, плюс MPS-тест для работы с кодом на этом языке.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

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

Вместе с MPSом, внутри него, поставляются разные языковые расширения, для работы с замыканиями, с коллекциями… и так далее. И некоторое количество языков для работы с XML, тупо для работы. Т.е. вы можете вводить XML, и что самое главное — генерировать XML из своего кода.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Ну и еще есть некоторое количество языков, которые предназначены для создания языков. MPS в плане создания языков вполне честно (??? 16:20)

Вместо демонстрации — выглядит как-то так ↑.

Я показывают не со своего компьютера, поэтому все, кого интересует демонстрация, приглашаю на стенд в коридоре. Тут посмотрите, как просто взять и заDSLлить поддержку языковой конструкции.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Фактически, это все, что я хотел рассказать, осталось несколько важных вещей.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

MSP подходит не только для создания языковых расширений, т.е. не только в Java можно добавить конструкций, которых в них не хватает, но также вы можете создавать какие-то собственные DSLи.

Вот например, Мартин Фаулер создал язык для описания своей финансовой отчетности.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Кроме того, с помощью MPSа мы написали YouTrack, такой большой багтрекер — большой, в смысле с большим количеством кода (сгеренированного). Но мой предыдущий опыт разработки подсказывает мне, что код содержательный, который мы пишем и редактируем, этого кода достаточно мало. Опять таки интересующимся, мы на выходе можем показать, как выглядит код в редакторе, сколько там таблиц. Кода достаточно мало, из-за того, что уровень абстракции поднят достаточно высоко. Для разработки YouTrack был создан набор языков, часть этих языков открыта, а часть — закрыта. Мы их пока не отдаем, потому что они не достигли пока продажного качества.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Вот, приложение настоящее, живое.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

У MPSа есть положительное свойство. Он «Apache 2.0»-лицензированный, абсолюно бесплатный, даже для коммерческого использования.

Language Oriented Programming (LOP) в действии (Максим Мазин, ADD-2011).pdf

Скачать его можно здесь. Теперь если у вас есть какие-то вопросы, предлагаю вам их задать.

(18:46)