TGViewer
PLComp PLComp @plcomp · 843 subscribers
Post #78 1.25K
https://dl.acm.org/doi/pdf/10.1145/3428297
Macros for Domain-Specific Languages

"Yo dawg I heard you like macros so I put macros in your macros so you can expand while you expand!"

Как ни забавно, эта фраза верно передаёт содержание статьи, а именно, два главных нововведения авторов: 1) введение пользовательской макросистемы для разрабатываемого пользователем же DSL (на макросах хост-языка, Racket в данном случае), и 2) переиспользование macro expander из хост-языка для реализации пользовательской системы макросов (за счёт предоставления API к определённым функциям macro expander).

Звучит круто, но зачем это нужно? Почему нельзя обойтись макросами хост-языка? На это снова можно выделить две причины.

Первое — это новые name binding constructs, работающие не так, как в хост-языке. Например, в статье рассматривается реализация PEG DSL, в котором конструкции захвата подвыражения и связывания его с именем могут находиться внутри звезды Клини. Но в таком случае эти имена связываются не с одним подвыражением, а со всем подсписком внутри списка выражений, порождённого звездой Клини. Например, в выражении
(define-peg arith-expr
(=> (seq (: e1 term) (* (seq (: op* (alt "+" "-")) (: e* term))))
(left-associate-binops e1 op* e*)))
идентификаторы op* и e* связываются со списками операторов и термов соответственно (так как находятся "под звёздочкой"), в то время как e1 связывается с одним термом.

По сравнению со стандартным связыванием имён в функциях или let-выражениях такие связывания работают "шиворот навыворот", а потому требуют реализации "руками". В данном примере такая реализация написана авторами PEG DSL на макросах хост-языка, но если мы хотим чтобы пользователи DSL могли запрограммировать binding constructs по собственному вкусу, нам придётся предоставить им развитую макро-систему поверх нашего DSL.

Вторая причина связана с тем, что авторы называют "hosted DSL". Мне кажется, иначе это можно было бы назвать "deeply embedded DSL". Суть в том, что DSL, который мы реализуем на макросах, является не просто синтаксическим сахаром, а требует полноценного конвейера компиляции, начиная (потенциально) с парсера вводимого нами синтаксиса, продолжая специфическим разрешением имён, нетривиальными binding context и scoping rules, возможно, проверкой типов или другим статическим анализом корректности программ, и заканчивая полноценным IR и оптимизациями. Для того чтобы дать пользователям писать макросы для такого DSL с помощью макро-системы хост-языка, нам придётся открыть доступ к внутренностям нашего компилятора чтобы пользователи могли порождать AST или даже IR нашего DSL, и "скармливать" его далее компилятору. В противном случае макросы смогут порождать только разрозненные куски (скомпилированного) DSL, связанные между собой вызовами анонимных (или не очень) функций хост-языка, которые компилятор нашего DSL проанализировать и оптимизировать уже не сможет.

Так вот, чтобы получить преимущества и того, и другого, нам придётся предоставить отдельную макро-систему поверх нашего hosted DSL. А поскольку реализовать хорошую макросистему (гигиеничную, с разделением фаз и интегрирующуюся с системой модулей хост-языка) очень непросто, было бы полезно переиспользовать возможности macro-expander хост-языка. Статья предлагает API, позволяющий это сделать.

#scheme #racket #macros #dsl
  • 👍 2
More from @plcomp
  1. Oct 10, 2025В наше время может сложиться впечатление, что компиляторы вне LLVM уже не создаются. Это,…
  2. Jun 16, 2025#видеозаписи Начинаем публиковать видео докладов sysconf 2025. Первым — выступление Петра…
  3. May 21, 2025Недавно удалось лично пообщаться с несколькими известными преподавателями разработки компи…
  4. Nov 26, 2024В ближайшее время в Москве пройдет три конференции, связанные с системным программирование…
  5. Sep 29, 2024Я и мой студент, Кирилл Павлов, опубликовали статью "Библиотека llvm2py для анализа промеж…
  6. Jul 23, 2024Первый интерпретатор просто использует эти функции напрямую для рекурсивного аннотирования…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →