让 SML 中的绑定和动态范围

问题描述

我正在 Coursera 上学习编程语言课程,但我无法理解以下有关静态和动态范围的示例。

考虑代码示例和与之相关的测验

fun f g = let val x = 9 in g() end
val x = 7
fun h() = x+1
val y = f h

y 在词法范围内(如在 ML 中)和下有什么值 动态范围(与机器学习不同)?

问题的答案是“词法作用域下有 8 个,动态作用域下有 10 个”,给出的原因是“在动态作用域下,函数 h 的主体最终会”看到" x 到 9 的本地绑定,如果我们删除这个本地绑定(因为它似乎没有用处),那么动态范围将导致一个未定义的变量。"

考虑下面的代码片段和解释为什么动态作用域不适用于这种情况。

fun f y =
 let val q = y+1 
 in fn z => q + y + z
 end
val g = f 4
val y = 5
val z = g 6

在动态范围下,现在对 g 6 的调用将没有意义:我们将尝试查找 q,但在调用站点的环境中没有 q。

在第一个示例中,我们考虑了 let 表达式“val x = 9”中的局部 val 绑定,而在第二个示例中未考虑“val q = y+1”。这背后的原因是什么?

解决方法

在第一个示例中,val x = 9 在调用 g() 时在作用域内,因此 g 可以在动态作用域规则下看到它。

在第二个示例中,val q = y+1 仅在 f 内的范围内。当在行 g 上调用 val z = g 6 时,它不在范围内。