“固定一个以λ 演算为核心的左到右传值调用源语言,以及答案类型 $R$。对源项 $e$,写 $\mathcal C\llbracket e\rrbracket k$ 表示“求值 $e$ 后把结…”
形式陈述 ​
传值调用(call-by-value)要求函数应用的运算位置先求值为函数、实参位置再求值为值,之后才执行 β-替换。在 λ 演算中可写为值规则
以及由小步语义的求值上下文
直觉
传值调用把实参计算完成后再交给函数,因此函数体中每次使用参数都只是在使用一个已经得到的值。它与现实机器的栈式调用和严格语言的直觉接近,也让副作用顺序较易预测。关键不是“复制值”还是“传地址”的实现细节,而是函数体开始前是否必须完成实参求值;语言仍可用引用、对象或共享指针表示这个值。由于会求值即使未被函数使用的参数,传值可能在本可忽略的发散或异常上停住。
例子与边界
令
边界在于“传值”不等于“没有共享副作用”。若值是可变对象的引用,把引用作为值传入仍允许函数修改同一对象。求值顺序也不是由 call-by-value 一词完全决定:语言还必须规定多个实参是从左到右、从右到左还是未指定顺序求值。
推论与应用
多数严格函数式语言和命令式语言采用某种传值调用核心语义。求值上下文可精确规定其顺序;CBV CPS 变换把顺序翻译成显式续延,CEK 抽象机则用环境和 ar/fn 帧执行同一策略。递归编码也必须尊重这一顺序:直接运行
类型安全证明通常以调用值的值形式引理和 β 规则为中心。与传名调用比较同一程序,可揭示严格性分析、惰性求值和副作用语义的差异。
参考资料
- Robert Harper, Practical Foundations for Programming Languages, 2nd ed., Cambridge University Press, 2016,Parts I–XVIII。
- Gordon D. Plotkin, A Structural Approach to Operational Semantics, DAIMI FN-19, 1981; reprinted 2004,Full report。