让 SML 中的绑定和动态范围

Let bindings and dynamic scope in SML

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

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

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

What value does y have under lexical scope (like in ML) and under dynamic scope (unlike in ML)?

问题的答案是“8 under lexical scope and 10 under dynamic scope”给出的原因是“Under dynamic scope, body of函数 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 内的范围内。当在行 val z = g 6.

上调用 g 时,它不在范围内