为什么在重新定义变量时使变量不可变并创建新条目?

Tim*_*Tim -2 sml immutability

在 SML 中,如果我是对的,默认情况下变量是不可变的。所以当我们尝试重新定义一个变量时

val y  = 100;
val y = 0.6;
y
Run Code Online (Sandbox Code Playgroud)

环境将有两个条目y。新条目隐藏原始条目。是不是和我们将原始条目中的值从 100 修改为 0.6 的效果一样?

  • 如果原始条目是在函数调用之外创建的,而新条目是在函数调用中创建的,那么当函数调用返回时,我们可以访问原始条目。

  • 如果两个条目都是在同一个“范围”中创建的,就像上面的例子一样,原始条目是否不可访问?

实际上,它在 SML 中与在命令式语言(如 C)中是不是一样的?在 SML 中使变量不可变并在重新定义变量时创建新条目有什么意义?

谢谢。

kop*_*ecs 5

是不是和我们把原始条目中的值从100修改为0.6一样的效果

不。考虑通过使用类似的闭包引用先前环境的代码

val x = 7
val f = fn () => x
val x = 8
val _ = print (Int.toString (f ())) (* prints 7 *)
Run Code Online (Sandbox Code Playgroud)

如果原始条目是在函数调用之外创建的,而新条目是在函数调用中创建的,那么当函数调用返回时,我们可以访问原始条目。

当然,它是静态范围的。

如果两个条目都是在同一个“范围”中创建的,就像上面的例子一样,原始条目是否不可访问?

它仍然可以访问,只是不能通过该标识符访问。考虑上面的例子。

在 SML 中使变量不可变并在重新定义变量时创建新条目有什么意义?

这样做的一种用途是更改变量的类型,同时仍使用相同的标识符(您在发布的示例中就是这样做的!)。以(在 C 中)为例:

int i = 7;
i = 7.0;
Run Code Online (Sandbox Code Playgroud)

在这里,i仍将是 类型int。参见,在 SML 中:

val i : int = 7
val i : real = 7.0
Run Code Online (Sandbox Code Playgroud)

我已经添加了用于说明的类型注释,但即使没有它也具有相同的行为。在第二次绑定之后,i有 type real