Предметно-ориентированный язык
Предметно-ориентированный язык (domain-specific language, DSL) — это язык программирования или формальная спецификация, предназначенный для решения задач в конкретной предметной области. В отличие от языков общего назначения (general-purpose language, GPL), таких как C++, Java или Python, DSL предоставляет ограниченный набор абстракций и синтаксических конструкций, максимально приближенных к терминологии и понятиям целевой области. Это позволяет специалистам, не являющимся профессиональными программистами (например, бухгалтерам, химикам, дизайнерам), формулировать решения на знакомом им языке, а также повышает производительность и читаемость кода для разработчиков, работающих в узкой сфере.
История
Концепция предметно-ориентированных языков возникла задолго до появления современных компьютеров. Одним из ранних примеров является язык нотации для музыкальных произведений, который позволяет композиторам точно описывать высоту, длительность и ритм звуков. В вычислительной технике первые DSL появились в 1950-х годах. Например, язык APT (Automatically Programmed Tools), созданный в Массачусетском технологическом институте в 1957 году, предназначался для программирования станков с числовым программным управлением (ЧПУ). Он позволял технологам описывать траектории движения инструмента на естественном для них языке, а не на ассемблере.
В 1960-х годах компания IBM разработала язык Report Program Generator (RPG) для генерации бизнес-отчётов из файлов данных. Его синтаксис был ориентирован на бухгалтеров и клерков, а не на программистов. В 1970-х годах появились языки для описания макетов страниц (например, troff и TeX), которые стали стандартом в научной и технической среде. В 1980-х годах распространение получили языки запросов к базам данных, в первую очередь SQL (Structured Query Language), который является одним из самых успешных и широко используемых DSL. SQL позволяет аналитикам и разработчикам манипулировать данными, не вдаваясь в детали их физического хранения.
В 1990-х и 2000-х годах с развитием веб-технологий и автоматизации тестирования появились такие DSL, как HTML (для разметки веб-страниц), CSS (для описания внешнего вида), Regex (регулярные выражения для поиска шаблонов в тексте) и Makefile (для управления сборкой проектов). В 2010-х годах концепция DSL получила новый импульс в связи с распространением методологии предметно-ориентированного проектирования (Domain-Driven Design, DDD), популяризированной Эриком Эвансом. DDD предлагает создавать DSL, которые отражают модель предметной области, что упрощает коммуникацию между разработчиками и экспертами в этой области.
Классификация
Предметно-ориентированные языки классифицируются по нескольким признакам.
По способу реализации
- Внешние DSL — это самостоятельные языки со своим синтаксисом и парсером. Они не зависят от языка общего назначения и обрабатываются отдельным интерпретатором или компилятором. Примеры: SQL, HTML, CSS, регулярные выражения, GraphQL.
- Внутренние DSL (встраиваемые) — это языки, реализованные внутри существующего языка общего назначения с использованием его синтаксических возможностей (например, перегрузки операторов, макросов, функций высшего порядка). Они не требуют отдельного парсера и выглядят как естественное расширение хост-языка. Примеры: библиотека jQuery для JavaScript, RSpec для Ruby, Linq для C#.
- Языки, порождённые из существующих — это подмножества или диалекты языков общего назначения, адаптированные для конкретной задачи. Например, Embedded SQL (встраивание SQL-запросов в код на C или COBOL) или C++ для программирования микроконтроллеров с ограниченным набором библиотек.
По области применения
- Языки запросов и манипуляции данными: SQL, SPARQL (для RDF-данных), XQuery (для XML).
- Языки разметки и описания данных: HTML, XML, JSON, YAML, Markdown.
- Языки описания пользовательских интерфейсов: QML (Qt), XAML (WPF), FXML (JavaFX).
- Языки для автоматизации сборки и конфигурации: Makefile, CMake, Ansible, Docker Compose.
- Языки для математических и научных вычислений: MATLAB, Wolfram Language, R (статистика).
- Языки для описания бизнес-правил и логики: Drools (система управления бизнес-правилами), Decision Model and Notation (DMN).
- Языки для тестирования: Gherkin (Cucumber), Selenium IDE (запись тестов веб-интерфейсов).
Устройство и характеристики
Основные характеристики DSL включают:
- Ограниченная выразительность: DSL предоставляет только те конструкции, которые необходимы для решения задач в своей области. Это делает его простым в изучении и использовании, но непригодным для задач вне этой области.
- Декларативность: Многие DSL являются декларативными, то есть описывают что нужно сделать, а не как (императивный подход). Например, SQL-запрос
SELECT * FROM users WHERE age > 18описывает желаемый результат, а не алгоритм его получения. - Близость к предметной области: Синтаксис и терминология DSL максимально соответствуют понятиям, используемым экспертами в этой области. Например, в языке для описания химических реакций могут использоваться названия веществ и условия реакции, а не переменные и циклы.
- Отсутствие универсальности: DSL не предназначен для написания операционных систем, веб-серверов или игр. Его задача — решать узкий круг задач эффективно и понятно.
Применение
DSL широко применяются в различных отраслях:
- Разработка программного обеспечения: SQL для работы с базами данных, HTML/CSS для вёрстки, Makefile для сборки, Gherkin для описания сценариев тестирования.
- Финансы и бухгалтерия: Языки для описания финансовых моделей (например, в Excel с помощью формул), расчёта налогов, генерации отчётов.
- Инженерия и производство: APT для ЧПУ-станков, VHDL и Verilog для проектирования цифровых микросхем, MATLAB/Simulink для моделирования динамических систем.
- Научные исследования: R для статистического анализа, Wolfram Language для символьных вычислений, Python с библиотеками NumPy/SciPy (часто используется как внутренний DSL для научных расчётов).
- Медицина: Языки для описания протоколов клинических испытаний, диагностических алгоритмов, форматов обмена медицинскими данными (например, HL7 FHIR).
- Веб-разработка: GraphQL для описания API, WebAssembly (хотя это скорее бинарный формат, его текстовое представление — WAT — является DSL).
Примеры
Внешний DSL: SQL
``sql SELECT product_name, price FROM products WHERE category = 'Electronics' AND price < 1000 ORDER BY price DESC; ``
Этот запрос не требует от пользователя знания циклов, условных операторов или управления памятью. Он просто описывает, какие данные и в каком порядке нужно получить.
Внутренний DSL: RSpec (Ruby)
``ruby describe Calculator do it "adds two numbers" do calc = Calculator.new expect(calc.add(2, 3)).to eq(5) end end ``
Библиотека RSpec использует синтаксис Ruby для создания читаемых описаний тестов. Ключевые слова describe, it, expect, to являются методами Ruby, но вместе они образуют DSL для тестирования.
Внутренний DSL: jQuery (JavaScript)
``javascript $('#myButton').click(function() { $(this).css('color', 'red'); }); ``
jQuery предоставляет цепочки вызовов методов, которые позволяют манипулировать DOM-элементами, не углубляясь в детали браузерных API.
Критика
Несмотря на преимущества, DSL имеют ряд недостатков:
- Сложность создания: Разработка качественного внешнего DSL требует написания парсера, интерпретатора или компилятора, что является нетривиальной задачей. Внутренние DSL проще в реализации, но ограничены возможностями хост-языка.
- Проблемы интеграции: DSL может быть плохо совместим с другими инструментами и системами. Например, код на SQL может быть сложно интегрировать с кодом на Python без использования дополнительных библиотек.
- Ограниченная переиспользуемость: DSL, созданный для одной компании или проекта, часто не может быть использован в других, что приводит к дублированию усилий.
- Узкая специализация: Разработчики, привыкшие к DSL, могут испытывать трудности при переходе на другие языки или при решении задач, выходящих за рамки DSL.
- Риск «языкового зоопарка»: В крупных проектах может накопиться множество DSL, что усложняет поддержку и обучение новых сотрудников.
Интересные факты
- Язык TeX, созданный Дональдом Кнутом, является одним из старейших и наиболее успешных DSL. Он используется для вёрстки научных статей и книг, и его синтаксис остаётся практически неизменным с 1978 года.
- Регулярные выражения (Regex) — это DSL для поиска и замены текста по шаблону. Они поддерживаются практически во всех современных языках программирования и текстовых редакторах.
- Концепция DSL лежит в основе low-code и no-code платформ, которые позволяют создавать приложения без написания традиционного кода, используя визуальные конструкторы и DSL-подобные скрипты.
- В 2010-х годах компания JetBrains разработала инструмент MPS (Meta Programming System), который позволяет создавать собственные DSL с визуальным редактором и генерацией кода на языках общего назначения.
Источники
- Фаулер, М. Предметно-ориентированные языки. — М.: Вильямс, 2011. — 576 с.
- Эванс, Э. Предметно-ориентированное проектирование (DDD): структуризация сложных программных систем. — М.: Вильямс, 2011. — 448 с.
- Ван Рой, П., Хариди, С. Сборник рецептов по языку программирования Python. — М.: ДМК Пресс, 2019. — 720 с.
- Domain-Specific Languages // Martin Fowler. — martinfowler.com/bliki/DomainSpecificLanguage.html (архивная версия).
- SQL — Structured Query Language // ISO/IEC 9075:2016. — Международный стандарт.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →