Предметно-ориентированный язык

Материал из Википедии — свободной энциклопедии
(перенаправлено с «Предметно-ориентированный язык программирования»)
Перейти к: навигация, поиск

Предметно-ориентированный язык (англ. Domain-specific language, DSL — «язык, специфический для предметной области») — язык программирования[источник не указан 204 дня], специализированный для конкретной области применения (в противоположность языку общего назначения[en], применимому к широкому спектру областей и не учитывающему особенности конкретных сфер знаний). Построение такого языка и/или его структура данных отражают специфику решаемых с его помощью задач[1]. Является ключевым понятием языково-ориентированного программирования.

Строго говоря, деление языков программирования на языки общего назначения и предметно-ориентированные весьма условно, особенно, если учесть, что формально любой протокол или формат файлов является языком. Существует масса языков общего назначения, применяемых в качестве предметно-ориентированных для определённых задач, и наоборот, предметно-ориентированных языков, применяемых в качестве языков общего назначения. Ярким примером является язык Си, разработанный в качестве кроссплатформенного ассемблера, но на практике применяемый гораздо шире. Язык ML, породивший целое семейство языков общего назначения (включая Haskell, ныне наиболее предпочитаемый разработчиками предметно-ориентированных языков в качестве базового), — изначально разрабатывался в качестве DSL для системы автоматического доказательства теорем LCF[en]. Примером, показывающим условность классификации, служит язык БНФ (и компилятор с него Lex/Yacc): с одной стороны, это яркий пример метаязыка, с другой — он предназначен для одной конкретной задачи.

Терминология[править | править вики-текст]

Простейшие предметно-ориентированные языки, используемые в одном конкретном приложении, часто называют «мини-языками»[2].

Мартин Уорд (англ. Martin Ward)[3] в работе «Language Oriented Programming»[4] (которая считается отправной точкой развития ЯОП), использовал термины «problem oriented» и «domain oriented», но в англоязычном научном сообществе прижился термин «domain-specific», причём именно «domain-specific language», а не «domain-specific programming language». В русскоязычной литературе по программированию встречаются варианты «доменно-специфичный», «проблемно-ориентированный», «предметно-ориентированный».

Фаулер[5] и Дмитриев[6] определяют понятие DSL как «урезанный язык программирования (в большинстве случаев неполный по Тьюрингу)».

Примеры[править | править вики-текст]

Ведущие исследователи языково-ориентированного программирования (Мартин Уорд, Пол Хьюдак[en], Валид Таха и другие) приводят следующие примеры предметно-специфичных языков в качестве классических[4][7][8]:

По мнению Валида Тахи, с позиции ЯОП Microsoft Excel оказывается едва ли не наиболее широко применяемым в мире языком программирования[8].

Другими примерами предметно-ориентированных языков служат FoxPro, командные языки операционных систем (языки пакетных заданий, такие как JCL, языки интерактивной командной оболочки — сценарные и пакетные), неполные по Тьюрингу языки структурирования данных (XML, .ini, .conf), язык Вики-разметки, языки моделирования (UML, GPSS), Erlang для многопользовательских серверов, функционирующих в бесперебойном режиме. Следует отметить, что примеры не всегда являются показательными, некоторые[какие?] предметно-ориентированные языки подвергаются критике.

Существуют языки программирования, встроенные в систему управления ресурсами предприятия (язык ABAP в SAP/R3, языки систем Галактика, Парус, 1С)[источник не указан 318 дней] и применяемые для их дополнения специфичными для конкретной организации модулями. Использование встроенного языка упрощает программирование специфичных задач, поскольку в языке изначально присутствуют понятия предметной области. Некоторые[какие?] геоинформационные системы и САПР также имеют встроенные языки программирования.

Ещё одним примером является G-код язык программирования устройств с числовым программным управлением (ЧПУ).

Встраиваемые языки[править | править вики-текст]

Временами компьютерные языки реализуются зависимым образом, т.е. «внутри» транслируемого языка, без которого эти языки не только не способны исполняться, но и зачастую не образуют целостную символьную систему и не обладают Тьюринг-полнотой. Такие языки называются «встраиваемыми предметно-специфичными языками» (англ. Embedded DSL, EDSL; иногда DSEL) или просто «встраиваемыми языками» (Embedded language)[7][9], а также «языками, реализованными поверх или на основе данного языка».

Текстовые языки[править | править вики-текст]

В дополнение к традиционному делению языков на интерпретируемые и компилируемые, встраиваемые языки вводят ещё несколько видов реализации языка:

  • чистое встраивание[7];
  • использование макросредств языка (и нередко отождествление их с термином «метапрограммирование»), которое, в свою очередь, подразделяется на[10]:
    • многостадийные вычисления (англ. multistage computations);
    • квазицитирование (известное из языка Lisp);
    • использование шаблонов.

С другой стороны, можно рассматривать реализацию встраиваемого языка как «реализацию без трансляции», подразумевая, что DSL будет являться синтаксическим и семантическим подмножеством языка, в который он встраивается[10].

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

Основных причин для разработки встраиваемых текстовых языков три:

  • ввод в исходный язык дополнительных возможностей, расширяющих спектр эффективно решаемых задач или синтаксически упрощающих решение часто встречаемых задач;
  • интенсивное ре-использование компонентов транслятора базового языка: парсера, механизма типизации, реализации тривиальных вещей (таких как арифметика чисел), оптимизатора и др. Это обеспечивает кратное снижение трудоёмкости реализации придуманного языка, а также высокий уровень качества реализации при использовании безопасного языка в качестве базового;
  • получение возможности эффективно смешивать свойства разных самостоятельных языков в единых фрагментах кода, формируя мультипарадигменный язык широкого профиля, исключая необходимость межъязыкового взаимодействия[en] и расширяя возможности оптимизации.

Наиболее частыми примерами языков первой группы могут служить реализации объектно-ориентированных возможностей в функциональных[11] или процедурных[12] языках, и классическим примером служит язык CLOS. Следует отметить, что термин «язык» здесь используется не всегда — временами говорят просто о «реализации в языке новых возможностей» или о «расширении языка подсистемой, нацеленной на решение определённых задач», и нет строго деления на «библиотеки» и «встраиваемые языки», т.к. формально любой API, протокол или структура данных может рассматриваться в качестве языка[13]. Так, например, неотъемлемой частью языка Lisp является встроенный не полный по Тьюрингу язык S-выражений.

Вторая группа встраиваемых языков наиболее полно представлена в сообществе языка Haskell, и потому сам Haskell временами определяют как «DSL для денотационной семантики»[7]. Примерами могут служить Elm и другие языки, представляющие функциональную реактивную парадигму, а также язык Curry. Временами также встречается похожее выражение в отношении Лиспа: «Lisp — это не язык, а среда для разработки языков». Примером языка, реализованного поверх Лиспа, может служить Qi[en]. Масса встраиваемых мини-языков реализована в языке OCaml посредством модуля CamlpX[en] компилятора. Язык Rebol также проектировался для программирования посредством интенсивной реализации встраиваемых мини-языков. В диалекте Лиспа Scheme посредством языка S-выражений реализован не полный по Тьюрингу язык SXML[en], воплощающий протокол XML встраиваемым образом.

Встраиваемый язык может иметь самодостаточную полную по Тьюрингу семантику, но тем не менее вместо независимой реализации ре-использовать компоненты базового языка (третья группа, смешение первых двух). Ярким примером является язык Schelog[14], реализующий семантику Пролога внутри диалекта Лиспа Scheme посредством продолжений, и превращающий Пролог из «самостоятельного» языка во встраиваемый. Традиционной учебной или «спортивной» задачей для многих функциональных языков служит реализация поверх рассматриваемого языка какого-либо другого, чаще всего языка логики предикатов первого порядка[15].

В контексте метаязыков самостоятельные языки временами называют «языками первого класса» (по аналогии с сущностями первого класса в языках), а встраиваемые — «объектными языками».

В подавляющем большинстве случаев встраиваемые языки имеют лишь одну поддерживаемую реализацию, и различия в результирующем машинном представлении кода на них зависят лишь от используемого транслятора базового языка. Однако, бывают и исключения — например, язык Concurrent ML (CML), расширяющий Standard ML конструкциями для явного параллелизма, имеет две принципиально различные реализации.

Визуальные языки[править | править вики-текст]

Один из языков (базовый или встраиваемый) может быть визуальным, что нередко применяется в пользовательском программировании[en] (англ. End-user development). Типичными примерами таких пар могут служить AutoLispAutoCAD и VBAMicrosoft Excel. Подобные пары образуют целостную интерактивную систему, и с точки зрения пользователя невозможно (и не нужно) определить, являются ли визуальные инструменты надстройкой, имитирующей команды встроенного текстового языка, или же текстовый язык управляет визуальными инструментами. Действительные взаимоотношения в этих парах определяются разработчиком.

В паре EmacsEmacs Lisp отношения более определённые. Лисп традиционно относится к метаязыкам, и в данном случае текстовый редактор надстраивается над ним как визуальный DSL, что и делает последний изменяемым и расширяемым.

В случае, когда оба языка являются визуальными, встраиваемые языки обычно называют иными терминами — плагинами, фильтрами и др., и не используют терминологию языково-ориентированного программирования. Формально же можно говорить, например, что для визуального мета-языка обработки графики Adobe Photoshop есть множество встраиваемых визуальных мини-языков (см. Photoshop plugin[en]).

Функциональные и логические языки программирования выглядят неестественно в визуальном окружении, т.к. ФП и ЛП в чистом виде запрещает побочные эффекты, и для взаимодействия с GUI их концептуальную целостность приходится нарушать. С педагогической т.з. считается желательным преподавание программирования с использованием консольных средств, чтобы сосредоточить внимание студентов на основах алгоритмизации, а не эргономики и тем более не процедурных навыков использования тех или иных IDE[16].

Преимущества и недостатки[править | править вики-текст]

Преимущества и недостатки использования в конкретной задаче конкретного DSL вместо языка общего назначения определяются гораздо явственнее, чем преимущества и недостатки использования одного языка общего назначения вместо другого: в большинстве случаев уже разработанный DSL оказывается концептуально неприменим к одним задачам и даёт бесспорный выигрыш по большинству показателей качества в других, а некоторые подзадачи вообще остаются нерешёнными до разработки DSL[4].

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

См. также[править | править вики-текст]

Примечания[править | править вики-текст]

  1. А.Я. Фридланд, Л.С. Чанамирова. Информатика и компьютерные технологии: основные термины : толковый словарь. — Астрель, 2003-01-01. — 270 с. — ISBN 9785170145461.
  2. Bentley - Little languages, 1986.
  3. Martin Ward's Homepage
  4. 1 2 3 Ward - Language Oriented Programming, 1994.
  5. Фаулер Языковой инструментарий: новая жизнь языков предметной области. — 2005.
  6. Сергей Дмитриев (JetBrains) Языково-ориентированное программирование: следующая парадигма // = RSDN Magazine. — 2005.
  7. 1 2 3 4 Hudak - Modular Domain Specific Languages and Tools, 1998.
  8. 1 2 Taha - Domain-Specific Languages, 2008.
  9. Mernik - Formal and Practical Aspects of Domain-Specific Languages, 2012.
  10. 1 2 Czarnecki, O’Donnell, Striegnitz, Taha - DSL implementation in metaocaml, template haskell, and C++, 2004.
  11. Bernard Berthomieu OO Programming Styles in ML. — LAAS Report #2000111, Centre National De La Recherche Scientifique Laboratoire d'Analyse et d'Architecture des Systèmes, 2000.
  12. Cello — library that introduces higher level programming to C
  13. Хопкрофт, Мотвани, Ульман - Теория автоматов, языков и вычислений, 2001.
  14. Schelog, 2003.
  15. Paulson - ML for the Working Programmer, 1996.
  16. Игорь Головин, Андрей Столяров Мультипарадигмальный подход к преподаванию программирования и роль свободного ПО // МГУ им.Ломоносова, Тезисы докладов II конференции разработчиков свободных программ "На Протве". — г. Обнинск, 2005.

Литература[править | править вики-текст]

Ссылки[править | править вики-текст]