В начале хотел отписаться в соседней темке, но потом понял, что не укладываюсь в её направление, так что сделаю отдельную. Да, и сразу хочу сказать, что вопросы платформ тут обсуждать не хочу — на этот предмет я уже полностью высказался в соседних темах. Т.е. понятно, что, если какой-то инструмент будет реализован скажем только под какой-нибудь там .net, то он будет отброшен из рассмотрения ещё до оценки его "dsl возможностей". Но здесь мы это обсуждать не будем — можно пока условно считать, что все инструменты реализованы под все платформы.
И так DSL. На мой взгляд вся эта область делится на две принципиально разных части: dsl исполняемые в процессе разработки ПО и dsl исполняемые в процессе работы ПО. Рассмотрим по отдельности.
1. DSL исполняемые в процессе работы ПО.
Речь о так называемых встроенных скриптах. Даже не буду приводить примеры — используется почти во всём сложном ПО. Гораздо интереснее рассмотреть способы реализации:
А. В большинстве случаев наиболее логичным и эффективным способом является встраивание какого-то из интерпретируемых языков общего назначения, с добавлением набора специфических для предметной области функций. Чаще всего это Lua, Python, JavaScript, но может быть и Lisp, Prolog и т.п. Конкретная реализация тривиальна: подключаем библиотеку языка, регистрируем свои предметные функции в движке; если требуется редактирование скриптов пользователем в самом приложение, то берём что-нибудь вроде QScintilla(там даже некое автодополнение работать будет). Данный подход позволяет не только получить "на халяву" готовый отлаженный интерпретатор, но и что самое главное, вылизанный годами эволюции синтаксис языка. Обычно разница с велосипедами очевидна (например достаточно взглянуть на убогий вид cmake скриптов в сравнение с scons/waf(использующие Python)). Но не всегда...
Б. В некоторых случаях всё же лучше разработать свой язык. Как успешный пример, используемый лично мною, могу назвать скажем OpenSCAD. Здесь, на мой взгляд, самым сложным является именно проектирование удобного непротиворечивого языка. И я не представляю какие инструменты (кроме ручки, бумаги и мозгов) могут помочь в этом. Так же очень важно хорошее знание предметной области. Однако после придумывания языка уже никаких особых проблем не возникает. Мы записываем формальную грамматику, берём какой-нибудь flex+bizon (или их аналоги для других платформ) и получаем готовый парсер. Интерпретатор же синтаксического дерева в таких случая обычно является просто исполнителем функций предметной области. В общем всё просто и уже давно разработано. Ну можно ещё добавить синтаксический модуль для нового языка в QScintilla, если требуется редактирование в самом приложение (как в том же OpenSCAD).
2. DSL исполняемые в процессе разработки ПО.
Обычно применяются для повышения эффективности работы программиста на каком-то языке общего назначения. Соответственно реализация очень сильно зависит от возможностей этого языка:
А. Реализация DSL через различные препроцессоры. В принципе не сложная вещь, применяемая обычно для мелких расширений базового языка. Соответственно это наиболее актуально для всяких там слабых языков (а зачем нам такие?). Хотя и в том же C++ есть свои известные вариации: moc (из Qt), ODB, AspectC++ и т.п. Однако для сильных развивающихся языков (а в особенности с наличием метапрограммирования) данный подход на мой взгляд является тупиковым. К примеру moc можно было давным давно выкинуть из Qt, а ODB после выхода нового стандарта. Ну и плюс надо отметить, что у этого подхода обычно большие проблемы с редакторами кода.
Б. Реализация DSL средствами самого языка (EDSL). Понятно, что в первую очередь тут идёт речь об использование метапрограммирования, причём только времени компиляции. Большинство динамических языков обладают базовой возможностью метапрограммирования, но т.к. оно отрабатывает только во время исполнения программы, то к повышению эффективности работы программиста это имеет слабое отношение (максимум синтаксический сахар). Т.е. в итоге сюда попадает один мейнстрим язык и несколько языков второго эшелона. В общем случае разработка EDSL вдвойне сложная задача, т.к. требуется одновременно и разработать удобный новый язык и как-то вместить его в синтаксис базового. Однако на моей практике я чаще всего встречался с EDSL, являющимися встроенными реализациями каких-то уже готовых известных языков, так что авторам оставалась только половина проблемы. Как примеры для C++: регулярные выражения — Boost.Xpressive, грамматики — Boost.Spirit, SQL — sqlpp11. Ещё бывает просто прямое отображение предметной области типа Boost.Unit — физические размерности. Или более сложный пример из D: html шаблонизатор в vibe.d, поддерживающий вставки нативного кода, является реализацией синтаксиса jade (а те утащили его у Haml). Кстати, с возможностями нового стандарта C++ можно попробовать замахнуться на подобные вещи и уж точно можно переписать указанные выше библиотеки вообще без синтаксического шума (задавать DSL конструкции обычными строками, но при этом разбираемыми во время компиляции). В целом с выходом нового стандарта и появлением в boost'е набора библиотек поддержки, метапрограммирование на том самом мейнстрим языке перестаёт быть таким уж диким кактусом, как было когда-то. Что довольно печально для языков второго эшелона, главным преимуществом которых является развитое метапрограммирование. Хотя до реального удобства конечно же ещё очень далеко. Ну и отдельно можно заметить, что данный подход не приносит никаких проблем с редакторами кода. Правда и автодополнения по EDSL языку тут получиться не удастся.
Подводя итоги.
Если мы говорим о каких-то инновационных инструментах для работы с DSL (Nemerle, Nitra и т.п.), то как я понял (поправьте, если что), они могут относиться только к пункту 2.Б. А что у нас тут может быть инновационного? Поддержка каких-то очень сложных EDSL? Сомнительно... Кстати, а хотя бы поддержка тех, что есть у мейнстрим языка имеется? Т.е. могу я скачать готовые к продакшену EDSL библиотеки работы с sql, регулярными выражениями, физическими размерностями, html-шаблонизатор с нативными вставками и т.п? Ну и даже если могу, то всё равно этого мало — новому языку надо быть заметно лучше мейнстрима, чтобы были какие-то шансы. Насколько я помню у Nemerle тут была одна потенциальная киллер-фича — автодополнение по EDSL. Но она же вроде только для одной сомнительной IDE, что опять же вычёркивает это преимущество для очень многих пользователей. И вряд ли есть путь, как расширить это на все редакторы. В итоге я пока так и не понял, что в принципе инновационного могут принести эти решения в работу с DSL. Даже если бы они были реализованы под все платформы, а не только под .net.
P.S. Оффтопик. Написал всё это и увидел, что в принципе в выборе .net'a есть определённый смысл: 1. там нет никаких конкурентов по МП, 2. там общепринята та самая IDE. В итоге при таком раскладе уже появляются определённые шансы... Конечно при условии, что многим .net программистам интересны подобные сложные темы (про это я уже высказывал большие сомнения).
Здравствуйте, alex_public, Вы писали:
_>И так DSL. На мой взгляд вся эта область делится на две принципиально разных части: dsl исполняемые в процессе разработки ПО и dsl исполняемые в процессе работы ПО. Рассмотрим по отдельности.
Не думаю, что есть смысл разделять.
_>А. В большинстве случаев наиболее логичным и эффективным способом является встраивание какого-то из интерпретируемых языков общего назначения, с добавлением набора специфических для предметной области функций.
И получаем тормоза и отсутствие статических проверок предметной области.
_>Данный подход позволяет не только получить "на халяву" готовый отлаженный интерпретатор,
Который ничего не знает про предметную область.
_>но и что самое главное, вылизанный годами эволюции синтаксис языка.
Синтаксис языка высасывается из пальца при его создании и никогда не меняется.
Так что не ясно, о какой эволюции ты говоришь.
В любом случае синтаксис дело десятое. Главное определить сущности предметной области.
_>Здесь, на мой взгляд, самым сложным является именно проектирование удобного непротиворечивого языка.
Он получается автоматически после того как определены сущности предметной области.
_>И я не представляю какие инструменты (кроме ручки, бумаги и мозгов) могут помочь в этом. Так же очень важно хорошее знание предметной области.
Без этого, ты вообще не сможешь ни какой софт, ни каким методом написать.
_>Однако после придумывания языка уже никаких особых проблем не возникает. Мы записываем формальную грамматику, берём какой-нибудь flex+bizon (или их аналоги для других платформ) и получаем готовый парсер.
1)Записать под них грамматику это те ещё пляски с бубном.
2)Восстановление после ошибок там считай что нет. Да и сами сообщения о ошибках такие, что волосы дыбом встают.
3)Что с типизацией делать будешь?
_>А. Реализация DSL через различные препроцессоры. В принципе не сложная вещь, применяемая обычно для мелких расширений базового языка. Соответственно это наиболее актуально для всяких там слабых языков (а зачем нам такие?).
С++ слабый. Я знаю про все его фишки. Просто я ещё и альтернативы знаю.
_>Ну и плюс надо отметить, что у этого подхода обычно большие проблемы с редакторами кода.
У С++ вообще проблемы с редакторами кода.
_>Большинство динамических языков обладают базовой возможностью метапрограммирования, но т.к. оно отрабатывает только во время исполнения программы, то к повышению эффективности работы программиста это имеет слабое отношение (максимум синтаксический сахар).
Это не правда. Наметапрограммировать на динамически типизированных языках можно очень много. Банальным сахаром они не ограничиваются.
Проблемы динамики: Тормоза и баги. Поэтому я и считаю все динамически типизированные языки ошибкой природы.
_>Т.е. в итоге сюда попадает один мейнстрим язык и несколько языков второго эшелона. В общем случае разработка EDSL вдвойне сложная задача, т.к. требуется одновременно и разработать удобный новый язык и как-то вместить его в синтаксис базового.
А ещё приходится бороться с убогой системой "метапрограммирования" С++ (ты же про него говоришь).
_>Кстати, с возможностями нового стандарта C++ можно попробовать замахнуться на подобные вещи и уж точно можно переписать указанные выше библиотеки вообще без синтаксического шума (задавать DSL конструкции обычными строками, но при этом разбираемыми во время компиляции).
Знал бы ты как немерле за такое с говном смешивают.
Линк в строке? ААААА!!! УУУУ!!!! КОООООШШШМАААР!!!
Ну и добавим сюда традиционные для С++ тормоза при компиляции и километровые сообщения об ошибках.
Нитре программирование в строках уже не нужно. Там парсер намного мощьнее, чем у немерле.
_>В целом с выходом нового стандарта и появлением в boost'е набора библиотек поддержки, метапрограммирование на том самом мейнстрим языке перестаёт быть таким уж диким кактусом, как было когда-то.
Не перестаёт.
_>Ну и отдельно можно заметить, что данный подход не приносит никаких проблем с редакторами кода.
Они как не работали, так и продолжат не работать.
_> Если мы говорим о каких-то инновационных инструментах для работы с DSL (Nemerle, Nitra и т.п.), то как я понял (поправьте, если что), они могут относиться только к пункту 2.Б.
Не только.
Компиляторы Nemerle и Nitra реализованы в виде ДЛЛ.
И нет никаких проблем запустить и во время исполнения.
Включая все сервисы ИДЕ внутри своего приложения. Те не "некое автодополнение", а полноценную ИДЕ с подсветкой типов, навигацией, полноценным автодополением, рефакторингом переименования, подсветкой ошибок в реальном времени итп. [Nitra] Autocompletion
_>А что у нас тут может быть инновационного? Поддержка каких-то очень сложных EDSL?
Не только.
Ещё и куча мелких специфических для задачи улучшений, которые могут сократить код в разы.
_>Кстати, а хотя бы поддержка тех, что есть у мейнстрим языка имеется?
Имеется. Ну, или пишется за неделю по вечерам.
_>Т.е. могу я скачать готовые к продакшену EDSL библиотеки работы с sql, регулярными выражениями, физическими размерностями, html-шаблонизатор с нативными вставками и т.п?
Можешь.
_>Ну и даже если могу, то всё равно этого мало — новому языку надо быть заметно лучше мейнстрима, чтобы были какие-то шансы. Насколько я помню у Nemerle тут была одна потенциальная киллер-фича — автодополнение по EDSL.
Да их тьма.
_>Но она же вроде только для одной сомнительной IDE, что опять же вычёркивает это преимущество для очень многих пользователей.
Оно к ИДЕ вообще не привязано.
Просто не нашлось желающих сделать это под другие ИДЕ. Вернее желающие были, но до рабочего состояния не довели.
Ибо засунуть поддержку языка в ИДЕ само по себе не простое занятие.
Ибо у каждой ИДЕ куча своих тараканов.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Интересно, что в языках и средах, где разделения на стадии компиляци и выполнения нету (т.е. динамических ЯП), DSL — это не «отдельная сложная идея», а простой и общепринятый паттерн проектирования. Т.е. в большой степени, любая domain specific library склонна определятя соответствующий своим целям domain specific language
Здравствуйте, WolfHound, Вы писали:
_>>И так DSL. На мой взгляд вся эта область делится на две принципиально разных части: dsl исполняемые в процессе разработки ПО и dsl исполняемые в процессе работы ПО. Рассмотрим по отдельности. WH>Не думаю, что есть смысл разделять.
Разница принципиальна. Одно — это инструмент создания приложения, а другое — это инструмент кастомизации готового приложения.
_>>А. В большинстве случаев наиболее логичным и эффективным способом является встраивание какого-то из интерпретируемых языков общего назначения, с добавлением набора специфических для предметной области функций. WH>И получаем тормоза и отсутствие статических проверок предметной области.
Однако индустрия однозначно выбрала динамические языки на роль встроенных скриптов. Я даже не знаю есть ли смысл приводить примеры... Они же просто вокруг. Вот даже в браузере сейчас печатаю и то JS отрабатывает.
Насчёт тормозов вопрос спорный. Если мы говорим о встроенных скриптах, то там же вся реальная работа происходит на базовом языке, а скриптовой играет роль системного клея. Для примера могу посоветовать попробовать посоревноваться на Nemerle в быстродействие численной математики скажем с Питоном, к которому подключён NumPy.
_>>но и что самое главное, вылизанный годами эволюции синтаксис языка. WH>Синтаксис языка высасывается из пальца при его создании и никогда не меняется. WH>Так что не ясно, о какой эволюции ты говоришь.
Ну да, т.е. C#6.0 вообще ничем не отличается от C#1.0... )))
_>>Однако после придумывания языка уже никаких особых проблем не возникает. Мы записываем формальную грамматику, берём какой-нибудь flex+bizon (или их аналоги для других платформ) и получаем готовый парсер. WH> WH>1)Записать под них грамматику это те ещё пляски с бубном. WH>2)Восстановление после ошибок там считай что нет. Да и сами сообщения о ошибках такие, что волосы дыбом встают. WH>3)Что с типизацией делать будешь?
А никто не собирается проектировать для встроенного скрипта язык уровня C++ или C#. ))) Посмотри на конкретные реальные примеры. Вот тот же OpenSCAD кстати очень полезный продукт, набирающий сейчас популярность.
_>>Ну и плюс надо отметить, что у этого подхода обычно большие проблемы с редакторами кода. WH>У С++ вообще проблемы с редакторами кода.
В CLion тоже?
_>>Большинство динамических языков обладают базовой возможностью метапрограммирования, но т.к. оно отрабатывает только во время исполнения программы, то к повышению эффективности работы программиста это имеет слабое отношение (максимум синтаксический сахар). WH>Это не правда. Наметапрограммировать на динамически типизированных языках можно очень много. Банальным сахаром они не ограничиваются. WH>Проблемы динамики: Тормоза и баги. Поэтому я и считаю все динамически типизированные языки ошибкой природы.
Дело не в этом, а в том что это метапрограммирование отрабатывает на этапе исполнения приложения, так что программисту от него пользы не больше, чем от любых других обычных конструкций языка. Вот к примеру, как ты сделаешь на Питоне (ну или любом другом аналогичном языке) автоматическую проверку корректности зашитого в код sql запроса?
_>>Кстати, с возможностями нового стандарта C++ можно попробовать замахнуться на подобные вещи и уж точно можно переписать указанные выше библиотеки вообще без синтаксического шума (задавать DSL конструкции обычными строками, но при этом разбираемыми во время компиляции). WH>Знал бы ты как немерле за такое с говном смешивают. WH>
WH>Линк в строке? ААААА!!! УУУУ!!!! КОООООШШШМАААР!!!
))) Не вижу в этом ничего плохого, если эта строка парсится и превращается в инструкции процессору на этапе компиляции.
_>> Если мы говорим о каких-то инновационных инструментах для работы с DSL (Nemerle, Nitra и т.п.), то как я понял (поправьте, если что), они могут относиться только к пункту 2.Б. WH>Не только. WH>Компиляторы Nemerle и Nitra реализованы в виде ДЛЛ. WH>И нет никаких проблем запустить и во время исполнения.
Т.е. речь про вариант 1.Б? Но там не нужен такой сложный язык в роли встроенного скрипта. Вообще без вариантов. Или же может ты имел виду построить в нём простенький EDSL? Но зачем такие сложности (тащить к клиенту ещё и Nemerle), когда можно обойтись только этим DSL'ем?
WH>Включая все сервисы ИДЕ внутри своего приложения. Те не "некое автодополнение", а полноценную ИДЕ с подсветкой типов, навигацией, полноценным автодополением, рефакторингом переименования, подсветкой ошибок в реальном времени итп. WH>[Nitra] Autocompletion
Для мелких скриптовых языков это всё вообще не актуально. Ну ты сам посмотри, где вообще применяются подобные DSL'и... Даже построенные на полноценных языках общего назначения такого не имеют — взгляни на консоль python'a/lisp'a во всяких CAD'ах или текстовых редакторах, а про консоль lua/python'a в играх я вообще молчу. ))) А в случае совсем маленького DSL (не на базе языка общего назначения), типа того же OpenSCAD или скажем CMake, про это вообще смешно упоминать.
_>>Кстати, а хотя бы поддержка тех, что есть у мейнстрим языка имеется? WH>Имеется. Ну, или пишется за неделю по вечерам.
Я ни на секунду не сомневаюсь, что на Nemerle можно легко повторить большинство DSL библиотек, написанных на C++. Но как бы есть очень большая разница между возможностью написания и возможностью скачать готовый отлаженный продукт. И мне кажется, что если уж язык специализируется на таких вопросах, то самые базовые вещи (типа регулярных выражений, SQL, html шаблонизатора) точно должны быть под рукой.
_>>Т.е. могу я скачать готовые к продакшену EDSL библиотеки работы с sql, регулярными выражениями, физическими размерностями, html-шаблонизатор с нативными вставками и т.п? WH>Можешь.
Ого, этого я не знал. Помню только про парсеры у вас. А кинешь прямые ссылки на остальное? ) Причём лучше даже не на сами библиотеки, а на какие-нибудь тестовые примеры их использования...
_>>Но она же вроде только для одной сомнительной IDE, что опять же вычёркивает это преимущество для очень многих пользователей. WH>Оно к ИДЕ вообще не привязано. WH>Просто не нашлось желающих сделать это под другие ИДЕ. Вернее желающие были, но до рабочего состояния не довели. WH>Ибо засунуть поддержку языка в ИДЕ само по себе не простое занятие. WH>Ибо у каждой ИДЕ куча своих тараканов.
Так о том и речь, что для всех не сделаешь. Да собственно даже для ведущих не факт, что выйдет. Помню одно время были популярны проекты чего-то типа локального мини-сервера, поставляемого с каждым языком, к которому умеют обращаться все редакторы для реализации подсветки и автодополнения. В итоге достаточно написать такой для своего языка и всё будет отлично везде. Только вот что-то эта тема протухла похоже...
Здравствуйте, Гест, Вы писали:
Г>Интересно, что в языках и средах, где разделения на стадии компиляци и выполнения нету (т.е. динамических ЯП), DSL — это не «отдельная сложная идея», а простой и общепринятый паттерн проектирования. Т.е. в большой степени, любая domain specific library склонна определятя соответствующий своим целям domain specific language
И в этом определение нет особого смысла, т.к. всё равно не будет никакой проверки правил этого языка до выполнения приложения. А уж при выполнение такие вещи проверяются одинаково в языках с любой типизацией, только вот программисту от этого уже мало пользы.
Здравствуйте, alex_public, Вы писали:
_>))) Не вижу в этом ничего плохого, если эта строка парсится и превращается в инструкции процессору на этапе компиляции.
Только вот в этом случае не получится получить от IDE хоть какую-то функциональность (примитивные подсветка и автодополнение работают в той же Intellij из коробки). Более того, написание плагинов к готовой IDE тоже превратится в довольно неприятное занятие.
Здравствуйте, alex_public, Вы писали:
_>Разница принципиальна. Одно — это инструмент создания приложения, а другое — это инструмент кастомизации готового приложения.
Как по мне так это одно и то же.
_>Однако индустрия однозначно выбрала динамические языки на роль встроенных скриптов. Я даже не знаю есть ли смысл приводить примеры... Они же просто вокруг. Вот даже в браузере сейчас печатаю и то JS отрабатывает.
Их просто реализовать легко.
Статически типизированный язык с выводом типов гораздо более сложная штука.
_>Ну да, т.е. C#6.0 вообще ничем не отличается от C#1.0... )))
Насыпали маленько сахара.
_>А никто не собирается проектировать для встроенного скрипта язык уровня C++ или C#. ))) Посмотри на конкретные реальные примеры. Вот тот же OpenSCAD кстати очень полезный продукт, набирающий сейчас популярность.
Это всё для любого языка нужно.
_>Дело не в этом, а в том что это метапрограммирование отрабатывает на этапе исполнения приложения, так что программисту от него пользы не больше, чем от любых других обычных конструкций языка. Вот к примеру, как ты сделаешь на Питоне (ну или любом другом аналогичном языке) автоматическую проверку корректности зашитого в код sql запроса?
В рантайме. Как и всё остальное.
Это и есть их главная пролема.
Но говорить что там слабое метапрограммирование просто не корректно.
_>))) Не вижу в этом ничего плохого, если эта строка парсится и превращается в инструкции процессору на этапе компиляции.
Расскажи это всяким ганжустасам.
_>Т.е. речь про вариант 1.Б? Но там не нужен такой сложный язык в роли встроенного скрипта. Вообще без вариантов. Или же может ты имел виду построить в нём простенький EDSL?
Да что угодно.
_>Но зачем такие сложности (тащить к клиенту ещё и Nemerle), когда можно обойтись только этим DSL'ем?
Так проще. Ибо писать всё это самому дурь редкостная.
_>Для мелких скриптовых языков это всё вообще не актуально.
Это не правда.
_>Ну ты сам посмотри, где вообще применяются подобные DSL'и... Даже построенные на полноценных языках общего назначения такого не имеют — взгляни на консоль python'a/lisp'a во всяких CAD'ах или текстовых редакторах, а про консоль lua/python'a в играх я вообще молчу. )))
Просто по тому, что ИДЕ это сложно. ИДЕ для динамически типизированных языков за гранью фантастики. Надёжно работающих ни одной не видел.
А если ИДЕ для языка будет получаться автоматически и встраиваться в приложения за день, то будет совсем другой расклад.
_>А в случае совсем маленького DSL (не на базе языка общего назначения), типа того же OpenSCAD или скажем CMake, про это вообще смешно упоминать.
Почему? Чем тебе помешает автокомплит включая имена файлов? Подсветка ошибок, включая не существующие имена? итп
_>Я ни на секунду не сомневаюсь, что на Nemerle можно легко повторить большинство DSL библиотек, написанных на C++.
Все. И ещё кучу того что на С++ не сделать.
_>Ого, этого я не знал. Помню только про парсеры у вас. А кинешь прямые ссылки на остальное? ) Причём лучше даже не на сами библиотеки, а на какие-нибудь тестовые примеры их использования... https://github.com/rsdn/nemerle/blob/master/snippets/Nemerle.Xml/Test/Main.n https://github.com/rsdn/nemerle/blob/master/Linq/Tests/Tests.n
make (s : string) : void
{
regexp match (s) {
| "a+.*" => printf ("a\n");
| @"(?<num : int>\d+)-\w+" => printf ("%d\n", num + 3);
| "(?<name>(Ala|Kasia))? ma kota" =>
match (name) {
| Some (n) => printf ("%s\n", n)
| None => printf ("noname?\n")
}
| _ => printf ("default\n");
}
regexp match (s) {
| @"(?<_a>.*)\)" => printf ("parens %s\n", _a);
| _ => ()
}
}
_>Так о том и речь, что для всех не сделаешь. Да собственно даже для ведущих не факт, что выйдет.
Ты не понял.
Все языковые сервисы универсальны.
Нужно просто реализовать тонну специфичных для ИДЕ интерфейсов.
_>Помню одно время были популярны проекты чего-то типа локального мини-сервера, поставляемого с каждым языком, к которому умеют обращаться все редакторы для реализации подсветки и автодополнения. В итоге достаточно написать такой для своего языка и всё будет отлично везде. Только вот что-то эта тема протухла похоже...
Скорее всего, по тому, что каждый редактор требовал свой протокол.
Те авторам языков всё равно нужно было написать код под каждый редактор.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, alex_public, Вы писали:
_>И в этом определение нет особого смысла, т.к. всё равно не будет никакой проверки правил этого языка до выполнения приложения. А уж при выполнение такие вещи проверяются одинаково в языках с любой типизацией, только вот программисту от этого уже мало пользы.
Ты никогда в жизни не сможешь объяснить это всяким мамутам.
Но всё же нужно понимать, что рантайм проверки убирают не все преимущества.
Метапрограммирование на динамически типизированных языках таки заметно сокращает код. И делает его декларативным. А это само по себе очень большая помощь разработчику.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
_>>Разница принципиальна. Одно — это инструмент создания приложения, а другое — это инструмент кастомизации готового приложения. WH>Как по мне так это одно и то же.
Для начала, этим могут заниматься разные люди с очень разным уровнем подготовки.
_>>Однако индустрия однозначно выбрала динамические языки на роль встроенных скриптов. Я даже не знаю есть ли смысл приводить примеры... Они же просто вокруг. Вот даже в браузере сейчас печатаю и то JS отрабатывает. WH>Их просто реализовать легко. WH>Статически типизированный язык с выводом типов гораздо более сложная штука.
Только не надо этого всего для скриптов. Ну вот сам смотри, как разница между выдачей ошибки при компиляции и при исполнение, если между ними пролегает 1 микросекунда? )
_>>Ну ты сам посмотри, где вообще применяются подобные DSL'и... Даже построенные на полноценных языках общего назначения такого не имеют — взгляни на консоль python'a/lisp'a во всяких CAD'ах или текстовых редакторах, а про консоль lua/python'a в играх я вообще молчу. ))) WH>Просто по тому, что ИДЕ это сложно. ИДЕ для динамически типизированных языков за гранью фантастики. Надёжно работающих ни одной не видел. WH>А если ИДЕ для языка будет получаться автоматически и встраиваться в приложения за день, то будет совсем другой расклад. _>>А в случае совсем маленького DSL (не на базе языка общего назначения), типа того же OpenSCAD или скажем CMake, про это вообще смешно упоминать. WH>Почему? Чем тебе помешает автокомплит включая имена файлов? Подсветка ошибок, включая не существующие имена? итп
Здравствуйте, _DAle_, Вы писали:
_>>))) Не вижу в этом ничего плохого, если эта строка парсится и превращается в инструкции процессору на этапе компиляции. _DA>Только вот в этом случае не получится получить от IDE хоть какую-то функциональность (примитивные подсветка и автодополнение работают в той же Intellij из коробки). Более того, написание плагинов к готовой IDE тоже превратится в довольно неприятное занятие.
Эмм, речь же про EDSL в виде строки или в виде каких-то конструкций языка. Что вменяемого может мне показать обычная IDE по этому поводу, если оно будет не строкой? ) Информацию о том, что за этим символом скрывается страшный шаблон (C++) или жирный макрос (Nemerle)? Нет, спасибо, такое мне совсем не интересно... )))
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Гест, Вы писали:
Г>>Интересно, что в языках и средах, где разделения на стадии компиляци и выполнения нету (т.е. динамических ЯП), DSL — это не «отдельная сложная идея», а простой и общепринятый паттерн проектирования. Т.е. в большой степени, любая domain specific library склонна определятя соответствующий своим целям domain specific language
_>И в этом определение нет особого смысла, т.к. всё равно не будет никакой проверки правил этого языка до выполнения приложения. А уж при выполнение такие вещи проверяются одинаково в языках с любой типизацией, только вот программисту от этого уже мало пользы.
Ну, типа, у нас, бедных нищасных недолюбленных разработчиков на динамических языках, СВЯ АТМСФЕРА.
Компиляцию (гарантированную проверку работоспособнсоти перед деплоем) нам заменяют тесты/спеки. Это, как ни странно, работает (*место для вашего флейма статика vs динамика*). Так уж вышло, что бОльшую часть прогрессивных фишек в мифический «мейнстрим» привносим мы. Выразительности проще проявляться в динамических языках, obviously.
С нашей точки зрения нищасных разработчиков на динамике есть разница не между «компайлтаймом» и «рантаймом», но между поведением кода, зависящего от внешних условий и кода, зависящего только от того, как мы его написали.
Здравствуйте, Гест, Вы писали:
Г>Компиляцию (гарантированную проверку работоспособнсоти перед деплоем) нам заменяют тесты/спеки. Это, как ни странно, работает (*место для вашего флейма статика vs динамика*).
Всё верно, в динамике тесты вместо компиляции. И соответственно совершенно непонятно зачем конструировать некие специальные объекты в коде (DSL'и), если для проверки их правил всё равно придётся писать тесты. Т.е. для динамических языков введение DSL'а абсолютно ничего не привносит (во всяком случае на этапе "компиляции"/тестирования).
Г>Так уж вышло, что бОльшую часть прогрессивных фишек в мифический «мейнстрим» привносим мы. Выразительности проще проявляться в динамических языках, obviously.
А почему мейнстрим стал мифическим? ))) Кстати, к нему и куча динамики вполне себе относится: JavaScript, PHP, Python...
P.S. Я вполне себе люблю писать на динамических языка (мой любимчик — Python). Но только короткие скрипты.
Г>Ну, типа, у нас, бедных нищасных недолюбленных разработчиков на динамических языках, СВЯ АТМСФЕРА.
А ты скажи, что не так Обмажемся свое динамикой и говнякаем
Г>Компиляцию (гарантированную проверку работоспособнсоти перед деплоем) нам заменяют тесты/спеки. Это, как ни странно, работает (*место для вашего флейма статика vs динамика*).
То, что оно работает, не значит, что оно работает правильно
Здравствуйте, alex_public, Вы писали:
_>Для начала, этим могут заниматься разные люди с очень разным уровнем подготовки.
Ну, так и в разработке могут принимать участие разные люди.
Скажем, когда я работал в Парусе, там было две команды.
Одна писала движок. Вторая писала логику на этом движке.
Уровень подготовки был очень разный.
Первая команда могла творить все, что в голову взбредёт. Второй было запрещено всё кроме того что разрешено, а разрешено им было весьма не много.
Дать второй команде ДСЛ, в котором можно было делать только то, что разрешено было-бы оптимальным решением.
Но в те времена я нитру ещё даже не придумал.
_>Только не надо этого всего для скриптов. Ну вот сам смотри, как разница между выдачей ошибки при компиляции и при исполнение, если между ними пролегает 1 микросекунда? )
Это не правда.
1)В случае со статикой ошибка будет подсвечена прямо в редакторе.
2)Логики может быть больше десятка строк и тогда все проблемы динамики в полный рост.
_>Не, ну если оно будет совсем "на халяву" (хотя бы в стиле подключения QScintilla) и при этом сумеет простые динамические языки, то тогда конечно было бы не плохо. Но я что-то сомневаюсь в таком чуде... )
Для статически типизированных в случае с нитрой будет совсем на халяву.
_>Ну это не совсем то, что я имел в виду (речь шла про какой-нибудь готовый известный синтаксис типа такого http://vibed.org/templates/diet#grammar,
Можно и такой. Работы на день.
_>а не голый html), но уже из этого кода понятно, что нужное можно легко получить из этого. Так что плюс. )
Из этого сделали NemerleWeb который гораздо круче простых шаблонизаторов.
_>Ммм, так эта реализация SQL основана на linq из .net или мне показалось из-за сходных названий?
А какую тебе надо?
Линк лучше чем голый SQL.
Но есть и вот такое: https://github.com/rsdn/nemerle/wiki/SQL-macros
_>Здесь не очень ясно без исходников, текстовая строка, задающая шаблон, доживает до рантайма или живёт только на этапе компиляции?
Если посмотришь внимательно, то заметишь что переменные прямо в регексах объявляются.
?<num : int>
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, alex_public, Вы писали:
_>Эмм, речь же про EDSL в виде строки или в виде каких-то конструкций языка. Что вменяемого может мне показать обычная IDE по этому поводу, если оно будет не строкой? ) Информацию о том, что за этим символом скрывается страшный шаблон (C++) или жирный макрос (Nemerle)? Нет, спасибо, такое мне совсем не интересно... )))
В случае с найтрой тебе покажут символ языка.
Причём что это за символ зависит от языка.
Это может быть .НЕТный тип, может быть SQL'ная таблица, может быть любая другая сущность предметной области.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, alex_public, Вы писали:
Г>>Компиляцию (гарантированную проверку работоспособнсоти перед деплоем) нам заменяют тесты/спеки. Это, как ни странно, работает (*место для вашего флейма статика vs динамика*).
_>Всё верно, в динамике тесты вместо компиляции. И соответственно совершенно непонятно зачем конструировать некие специальные объекты в коде (DSL'и), если для проверки их правил всё равно придётся писать тесты. Т.е. для динамических языков введение DSL'а абсолютно ничего не привносит (во всяком случае на этапе "компиляции"/тестирования).
Тут, чтобы о чём-нибудь разговаривать, нужно бы согласовать словари.
1. Что такое DSL?
2. Зачем нужне DSL?
3. Может ли DSL быть определён без выхода за рамки «базового» языка?
Мои ответы (на единственность и непогрешимость которых я не претендую) таковы:
1. Это сущности и операции с ними, отражающие некую предметную область (domain)
2. Чтобы иметь возможность программировать некую логику в рамках заданной предметной области эффективно и выразительно
3. Да, в достаточно гибком и выскоуровневом языке
Тупой пример:
class User < ActiveRecord::Base
# вот это, добрые люди, DSL:
has_many :posts
scope(:for_fetching){where(fetch_date < Time.now)}
validations do
validate_presence :name
end
end
Какое «значение» имеет такой DSL? Да тупо меньше писать, чтобы добиться того же эффекта. Меньше писать — больше можно написать (или будет написано то, чего иначе не возникло бы, скажем валидации).
Несмотря на отсутствие стадии «компиляции», бОльшая часть этого кода, выполняемая на этапе «определения класса», если его неверно написать, упадёт при первой же загрузке (в т.ч. если скажем таблицы БД posts не существует в природе, или ты ошибся и написал pots).
То есть не надо даже сложные тесты писать — достаточно загрузить код, и DSL либо заработает, либо обломается.
Г>>Так уж вышло, что бОльшую часть прогрессивных фишек в мифический «мейнстрим» привносим мы. Выразительности проще проявляться в динамических языках, obviously.
_>А почему мейнстрим стал мифическим? ))) Кстати, к нему и куча динамики вполне себе относится: JavaScript, PHP, Python...
«Мифический мейнстрим» — это послание в соседний тред, где оказалось, что мейнстрим состоит из 4-5 языков
Здравствуйте, WolfHound, Вы писали:
_>>Для начала, этим могут заниматься разные люди с очень разным уровнем подготовки. WH>Ну, так и в разработке могут принимать участие разные люди. WH>Скажем, когда я работал в Парусе, там было две команды. WH>Одна писала движок. Вторая писала логику на этом движке. WH>Уровень подготовки был очень разный. WH>Первая команда могла творить все, что в голову взбредёт. Второй было запрещено всё кроме того что разрешено, а разрешено им было весьма не много. WH>Дать второй команде ДСЛ, в котором можно было делать только то, что разрешено было-бы оптимальным решением.
Так о том и речь. Причём этот DSL очевидно должен быть очень простой. А в тоже самое время первая команда могла параллельно использовать какой-нибудь мегасложный DSL на макросах, для статической проверки каких-то правил в своём коде.
_>>Только не надо этого всего для скриптов. Ну вот сам смотри, как разница между выдачей ошибки при компиляции и при исполнение, если между ними пролегает 1 микросекунда? ) WH>Это не правда. WH>1)В случае со статикой ошибка будет подсвечена прямо в редакторе.
А кто мешается сделать так же с динамикой? ) У нас же это всё внутри одного приложения...
_>>Ммм, так эта реализация SQL основана на linq из .net или мне показалось из-за сходных названий? WH>А какую тебе надо? WH>Линк лучше чем голый SQL.
Да, вот так отлично) Хотя понятно, что любители C# такое не воспримут и захотят только Linq вариант. )))
_>>Здесь не очень ясно без исходников, текстовая строка, задающая шаблон, доживает до рантайма или живёт только на этапе компиляции? WH>Если посмотришь внимательно, то заметишь что переменные прямо в регексах объявляются. WH>
WH>?<num : int>
WH>
Нуу в случае метапрограммирования всякое может быть, надо уточнять.))) Даже на плюсах можно захватить имя переменной через макрос и устроить потом по нему связывание в рантайме. )))
Если здесь всё во время компиляции, то мне нравится, классно! ) Особенно в сочетание с ПМ. )
Здравствуйте, WolfHound, Вы писали:
_>>Эмм, речь же про EDSL в виде строки или в виде каких-то конструкций языка. Что вменяемого может мне показать обычная IDE по этому поводу, если оно будет не строкой? ) Информацию о том, что за этим символом скрывается страшный шаблон (C++) или жирный макрос (Nemerle)? Нет, спасибо, такое мне совсем не интересно... ))) WH>В случае с найтрой тебе покажут символ языка. WH>Причём что это за символ зависит от языка. WH>Это может быть .НЕТный тип, может быть SQL'ная таблица, может быть любая другая сущность предметной области.
Угу, я уже понял что у вас в этом смысле всё круто. Правда только для одной IDE (от использования которой я отказался ещё несколько лет назад). А то я писал про вариант с DSL в обычных IDE.
Здравствуйте, Гест, Вы писали:
Г>Тут, чтобы о чём-нибудь разговаривать, нужно бы согласовать словари.
Хорошо, сейчас поясню всё на простейшем примере, основываясь на описанной мною в первом сообщение классификации.
Вот смотри, если пока отвлечься от вопросов динамики/статики и просто рассмотреть такой классический очевидный DSL, как регулярные выражения, то к какому пункту моей классификации он относится? Правильный ответ: или 1.Б или 2.Б, в зависимости от реализации. Т.е. в первом случае мы имеем подключение классической библиотечки регулярных выражений, работающей с зашитой в код приложения текстовой строкой (исполняет здесь роль встроенного скрипта). Если программист ошибся в этой строке (ввёл выражение, нарушающее синтаксис регулярных выражений), то мы узнаем об этой ошибке только в процессе исполнения приложения (вне зависимости от типа базового языка программирования). Во втором случае (использования библиотеки типа Boost.Xpressive в C++ или тут приводился выше пример кода для Nemerle) в коде приложения не будет находиться никаких строк (т.е. итоговое приложение не содержит DSL скрипт), а будет только бинарный код, очевидно валидный (по построению).
Так вот возвращаясь к динамике/статике. Моя основная мысль была в том, что на языке со статическим метапрограммированнием возможна реализация DSL как типа 1.Б (имеет смысл применять только если исполняемый "скрипт" запрашивается снаружи, а не зашит в приложение), так и типа 2.Б. А в языках с динамическим метапрограммированием в принципе возможен только тип 1.Б.