====== XLang:可逆计算的编译期语言族 ====== 可逆计算公式中有一个关键操作:**变换**。DSL 定义完后,需要经过结构变换才能得到最终的可运行产物。这个变换由 XLang 完成。 XLang 不是一门语言,而是一整套面向 DSL 变换的语言族,包含 XScript、Xpl、XTransform 三个核心成员。它们共享同一个类型系统和运行时,各自负责不同的变换任务。 ===== 为什么需要一门新语言 ===== 通用的编程语言(Java、Python)操作 XML/JSON 时,通常需要经过"解析 → 对象 → 遍历 → 修改 → 序列化"的冗长流程。对于 DSL 的编译期变换来说,这个流程太重了。 XLang 的设计目标是在 DSL 的结构层次上直接操作,而不是把 DSL 转成内存对象再处理。这类似于 SQL 直接在表上操作,而不需要把表转成对象再遍历。 用 XLang 表达"删除实体中的 password 字段": for (entity in /orm/entities) { entity.removeColumn("password") } 对比 Java 实现同样的逻辑: - 解析 XML → 20 行 - 遍历实体 → 5 行 - 查找并删除字段 → 5 行 - 序列化回 XML → 5 行 - 总共约 35 行 XLang 直接在内建的 XNode 结构上操作,没有解析和序列化开销。 ===== XScript:脚本语言 ===== XScript 是一门类似 JavaScript 的动态脚本语言,语法上兼容 JavaScript 的基础表达式,但针对树结构操作做了专门扩展。 let entity = xpl.loadXml("/nop/auth/orm/app.orm.xml"); let columns = entity.$children("columns").$children("column"); for (let col in columns) { if (col.$attr("name") == "password") { col.$remove(); } } xpl.saveXml("/nop/auth/orm/app.orm.xml", entity); XScript 中的 $ 前缀方法($children、$attr、$remove)是操作树结构的专用 API,直接在 XML 节点上执行,不需要经过 Java 对象映射。 **使用场景:** * 编译期的模型变换和修正 * 动态生成 DSL 片段 * 条件化处理(根据环境变量选择不同的模型) ===== Xpl:模板语言 ===== Xpl 是类似 FreeMarker 的模板语言,但它的输出是结构化数据(XML 节点),而非字符串。这避免了字符串拼接导致的 XML 格式错误。 Xpl 在服务端渲染时直接输出 XNode 树,不会产生无效的 XML 字符串。这意味着它可以安全地与 x-extends 合并引擎配合——合并引擎在结构树层面操作,不需要解析字符串。 **使用场景:** * 代码生成器的模板文件 * 报表模板 * 前端页面描述 ===== XTransform:树结构变换语言 ===== XTransform 是专门为"一棵树变成另一棵树"设计的声明式变换语言。你描述"输出结构",框架自动推导出从输入到输出的映射关系。 XTransform 是可逆计算中"Generator"的具体实现载体——它定义了如何将一种 DSL 结构变换为另一种 DSL 结构。 **使用场景:** * ORM 模型 → GraphQL Schema * 数据模型 → 前端表单描述 * API 模型 → gRPC Proto 定义 ===== 共享基础设施 ===== 三个语言共享同一套基础设施: * **类型系统**:统一的数据类型,与 XDef 类型系统一致 * **函数库**:内置 200+ 标准函数,涵盖字符串、日期、集合、XML 操作 * **调试器**:nop-idea-plugin 支持断点调试所有 XLang 语言 * **IDE 支持**:语法高亮、代码补全、文件跳转 ===== 与通用语言的对比 ===== ^ 对比维度 ^ Java/Python ^ XLang ^ | 操作对象 | 内存对象 | 结构树(XNode) | | 解析序列化 | 每次都要 | 不需要 | | 类型系统 | 静态/动态 | 面向 DSL 的类型 | | IDE 支持 | 成熟 | 基于 XDef 自动生成 | | 适用范围 | 通用 | DSL 变换 | XLang 的设计哲学是:**在 DSL 的结构层次上思考,而不是在通用语言的抽象层次上思考**。这正是面向语言编程(LOP)在工具层面的体现。 ===== 进一步阅读 ===== * [[xdef_meta_model|XDef 元模型体系]] * [[why_dsl|为什么可逆计算要求以 DSL 形式存在]] * [[overview|实现机制概览]]