====== 为什么可逆计算要求以 DSL 形式存在 ======
可逆计算的核心操作是"提取差量"和"合并差量"。但这两步操作的前提是:**你能精确地说出结构 A 和结构 B 之间差了什么**。
这不只是一个技术问题,而是一个本质性的认识论问题。
===== 代码是"不透明"的 =====
看两段 Java 代码:
// 版本 A
public void save(Entity entity) {
dao.save(entity);
sendNotification(entity);
}
// 版本 B
public void save(Entity entity) {
dao.save(entity);
sendNotification(entity);
logAudit(entity);
}
版本 B 比版本 A 多了一行 ''logAudit(entity)''。你能看出这个差异,是因为你知道"第4行有变化"。
但如果代码被格式化了呢?如果变量名改了呢?如果方法重构成了多函数呢?两个函数之间的差异就不再是"多了一行"那么清晰了。
问题在于:**通用代码的语言结构是松散的**。同样的语义可以用无数种方式表达,差量提取的结果依赖于格式、命名约定、代码风格等人为因素。这不是一个稳定的、可计算的结构。
相比之下,一段结构化的 DSL 定义:
每个节点、每个属性都有明确的含义和固定的位置。两个 DSL 之间的差异可以精确到"第二个 column 后面新增了一个 column"。这是**结构化的、可计算的差异**。
===== 可计算的前提:结构 =====
"可计算"意味着操作可以被算法精确执行,不需要人的判断。这要求操作对象具有**严格的结构约束**。
DSL 满足这个要求:
* **定义明确**:每个元素有固定含义,由 XDef 元模型约束
* **位置固定**:同义表达没有多种写法,减少了歧义
* **可枚举**:所有合法元素的集合是可知的
通用代码不满足这个要求:
* **表达自由**:同一种逻辑可以用循环、递归、函数式、流式等多种写法
* **边界模糊**:一个方法从哪里开始、到哪里结束,取决于人的习惯
* **隐式依赖**:全局变量、上下文、反射调用,使结构分析复杂化
可逆计算选择了 DSL,不是因为 DSL 更"高级",而是因为只有结构化的 DSL 才能支撑程序化的差量提取和合并。
===== 三个核心能力的来源 =====
可逆计算的三个操作——提取差量、存储差量、合并差量——都依赖 DSL 的结构化特性。
**提取差量依赖结构化**
只有两个元素在同一个精确的位置上,才能说这个属性"从 X 变成了 Y"。通用代码中,同一个逻辑可以用完全不同的代码结构表达,无法精确比较。
**存储差量依赖结构化**
差量需要独立于原始结构存在。对于通用代码,差量就是 patch 文件——它在行级别工作,一旦原始代码的某一行因为格式化而移动,patch 就失效了。对于 DSL,差量在元素级别工作——新增字段、删除属性、替换配置,不受空格和换行的影响。
**合并差量依赖结构化**
多层差量叠加时,需要明确"上层覆盖下层"还是"上层追加到下层"。结构化树(XML/JSON)上的合并规则是通用的——每个节点都可以附带 x:override 指令。行级别的 patch 无法表达"删除这个元素"或"替换这个子节点"这种语义。
===== 更直接的类比:数据库与代码 =====
数据库也是结构化的:每一行有固定的列,每条 SQL 查询返回可预测的结果。所以数据库可以做增量同步、主从复制、数据对比——这些都是差量操作。
但如果把数据存成一个个文本文件,用 grep 和 sed 来操作呢?能做增量同步吗?不能。因为文本文件的含义不再被明确定义了。
**DSL 对于可逆计算,相当于数据库表结构对于数据操作**。结构是一切可计算操作的前提。
===== 这不是一种限制,而是一种赋能 =====
把业务逻辑用 DSL 表达,表面上多了一层抽象。但这层抽象带来的收益远大于成本:
* **DSL 比通用代码更短**:50 行 DSL 胜过 500 行 Java
* **DSL 更容易分析**:AI 操作结构化 DSL 比操作散乱代码可靠得多
* **DSL 的 IDE 支持自动生成**:XDef 定义后,语法提示、验证、调试全自动
* **DSL 的差量机制解决软件定制化的核心难题**:不修改源码即可增删改功能
可逆计算选择 DSL,不是因为教条,而是因为离开了结构化,差量提取和合并就是不可计算的。
===== 进一步阅读 =====
* [[.:overview|reversible_computing_implementation 目录]]
* [[.:xdef_meta_model|XDef 元模型体系]]
* [[../reversible_computing|可逆计算:下一代软件构造理论]]