В рамках нашей работы по разработке подходов моделирования на языке Lean мы сталкиваемся с понятием уровней (levels). В традиционном моделировании такие уровни обычно называют моделью и метамоделью. С нашей точки зрения, эти понятия описывают одну и ту же фундаментальную сущность, обладающую следующими ключевыми свойствами:
Каждый уровень (level) определяет некоторую структуру объектов (Named Objects).
Эта структура задаётся в рамках определённой метамодели (отношение «модель–метамодель»).
Та же самая структура может сама выступать в роли метамодели для другого уровня (отношение «метамодель–модель»).
В текущей реализации, чтобы явно описывать такие структуры и обеспечивать приватные пространства имен, мы используем механизм namespace
языка Lean. Однако namespace является общей конструкцией и может использоваться не только для уровней моделей, но и для других сущностей, таких как аспекты, контексты и т.д. Это потенциально может привести к путанице или снизить читаемость кода.
Чтобы избежать подобной двусмысленности, улучшить читаемость и явно обозначить модельные уровни в коде, предлагается ввести новый синтаксис с использованием отдельного ключевого слова Level
, функционально аналогичного namespace
. Введение такого специального синтаксиса позволит:
Чётко отличать уровни моделей от других возможных сущностей.
Сделать код более выразительным и понятным.
В дальнейшем проще расширить или изменить поведение конструкции Level
, если появится такая необходимость.
В следующем разделе представлено практическое описание реализации этой идеи с помощью механизма макросов Lean, позволяющее легко перейти на более сложные формы реализации, если это потребуется в будущем.
Пока мы не хотим менять поведение обычного пространства имен (namespace
), а лишь хотим использовать более выразительное слово (Level
), лучшим и самым простым решением является использование макроса.
Это позволит нам:
Повысить читаемость кода.
Сохранить стандартное поведение namespace.
Легко перейти к более сложному поведению позже (через User Commands и кастомные парсеры), если потребуется.
⚙️ Реализация через простой макрос:
$$
-- Определение нового синтаксиса:
syntax "Level " ident " where " many1(command) "end" : command
-- Макрос, преобразующий конструкцию Level в namespace:
macro_rules
| (Level $name:ident where $commands* end) =>
(namespace $name
$commands*
end $name)
$$
📌 Пример использования нового синтаксиса:
Вместо:
$$
namespace MOF
structure Class where
name : String
properties : List String
end MOF
$$
Теперь мы пишем более читаемо:
$$
Level MOF where
structure Class where
name : String
properties : List String
end
$$
Это развернётся в точности в предыдущий вариант с namespace
.
🛠️ Как в дальнейшем перейти к более сложному поведению (если потребуется):
Если понадобится усложнить или полностью изменить поведение слова Level
(например, проверять дополнительные условия, генерировать специфические декларации и т.п.), мы вернёмся и заменим текущий простой макрос на:
При этом уже существующий код, написанный с использованием простого макроса, не потребует больших изменений, т.к. синтаксис останется тем же.