“异常语义连接操作语义、续延和效应系统。把正常与异常路径编译成成功/失败双续延的完整条款见CPS 变换;异常表与栈展开则是另一类常见运行时实现。在代数效应处理器中,异常可表现为 operati…”
形式陈述 ​
固定一个左到右传值调用源语言和答案类型
类型翻译可取基础类型
若源项有
对闭合、纯、确定的源语言,一种语义保持陈述是:若
直觉 ​
直接风格函数“返回”结果,CPS 函数则收到一份结果去向,并在完成时调用它。原本藏在宿主调用栈中的“接下来做什么”变成普通函数参数。每个中间结果都立刻交给下一段控制,因此翻译后的核心项可整理成尾调用形式。
CPS 是系统变换,不只是把某个回调手写出来。语法的每一种构造都必须有条款,条款共同保存源语言的求值顺序、作用域与控制效果。翻译后出现的 λf、λv 以及“立即构造再立即调用”的小函数,是变换制造的行政结构,不代表源程序新增业务计算。
例子与边界 ​
令 square 3 + 1,把加法也按左到右翻译,有
中间的 λw.k(u+w) 接到常量 k(u+1);消除这类 administrative redex 可缩短目标程序,但必须保持绑定和求值顺序。
异常可翻译成同时接收成功续延与失败续延的双续延程序,抛出时调用失败续延。这只是特定源语言的一种 CPS 实例。带状态、受限控制、调用名或不同答案类型的语言会产生不同翻译;不存在一套脱离源/目标语义仍“完全保序”的唯一公式。
推论与应用 ​
CPS 使异常、非局部跳转和一等控制成为显式函数调用,也常用作编译器中间表示。对有限种续延函数做 defunctionalization,可把它们变成抽象机器的帧;这解释了显式控制栈如何由高阶求值器导出。
正确的编译器证明还需区分类型保持、终止结果保持、发散反射与上下文等价等目标。单看生成项“能运行”不足以证明变换正确;行政归约和优化也必须在已声明的源—目标观察关系下验证。
参考资料
- Gordon D. Plotkin, “Call-by-Name, Call-by-Value and the λ-Calculus,” Theoretical Computer Science 1, 1975。
- Olivier Danvy and Andrzej Filinski, “Representing Control: A Study of the CPS Transformation,” Mathematical Structures in Computer Science 2(4), 1992。
- Andrew W. Appel, Compiling with Continuations, Cambridge University Press, 1992。