我处于一个很大的困境,请使用以下代码编写ML:
val x = 1
fun f(y) = x + y
val x = 2
val y = 3
val z = f (x + y)
z的值是6.现在,如果我在python中编写相同的代码,则z的值将为7.并且两种语言都声称(实际上教授这些语言的教师声称这样)具有词法/静态范围。但看起来只有ML才能通过使用在f被称为f / f>时定义f函数时创建的环境来实现它
任何指针都将非常感谢!
谢谢!
答案 0 :(得分:7)
在Python中,闭包是变量,而不是值。因此,当您在函数中引用x
时,它会引用分配给x
的最新值,而不是定义函数时x
的值。这会得到非直观的结果,如下所示:
adders = []
for x in range(10):
adders.append(lambda y: x+y)
您打算创建一个将x
添加到值的函数列表,其中x
在0到9之间变化,但是它们都添加9,因为它是{{1的值在循环结束时。
您可以使用默认参数来覆盖它,以便在函数定义时将名称绑定到其值。
x
在这个例子中,你甚至没有真正处理一个闭包:x = 1
f = lambda y, x=x: x + y # x inside f is now locked at 1
x = 2
y = 3
z = f(x + y)
这里实际上是一个全局变量。在Python中,只有在另一个函数内定义函数时才能创建闭包,而顶级或模块全局命名空间不是函数。但同样的原则也适用:在定义函数后,显然可以更改全局变量,因此如果要在函数定义时“锁定”其值,则使用默认参数。
答案 1 :(得分:6)
在ML中 - 至少在ML的功能部分 - 没有变量赋值这样的东西。声明val x = 1
后,您无法更改x
的值。
当你说x
时,你会引入一个名为val x = 2
的全新变量,它基本上只是隐藏旧的变量。但是函数x
已经被定义为指向原始的f
,所以它不受影响。
ML确实支持mutable types,它可以像Python中的变量一样重新分配。但他们偏离功能范例,你应该很少有任何理由使用它们。如果你想这样编程,Python就是一个更好的语言。