【发布时间】:2013-04-23 05:51:29
【问题描述】:
R 是一种函数式语言,但在以下情况下它的行为类似于 C# 而不是 F#。
在R中
f <- function() x
x <- 15
f() // prints 15
x <- 20 // shadowing
f() // prints 20
在 C# 中
int j = 15;
Action<string> funs = x => Console.WriteLine(j);
funs("foo"); // prints 15
j = 20; // mutate
funs("foo"); // prints 20
在 F# 中
let x = 15
let f y = x
f() // prints 15
let x = 20 // shadowing, to mimic R (purely functional)
f() // prints 15, not 20
在 R 中,该示例违反了我对“闭包通过值或引用关闭变量”的理解。在 C# 中,闭包通过引用关闭变量。在 F# 中,这并不重要,因为变量是不可变的。但在 R 中,似乎闭包只关闭符号名称,(确定不是通过值,因为它确实改变了;不是通过引用,因为变量是不可变的,所以它不是变异而是被遮蔽)。
那么,闭包有 3 种方式关闭变量,按值、按引用和按名称?
在这种情况下,是否还有其他函数式语言的行为类似于 R?
这里,hadley 的 book 中定义的 Dynamic Lookup 似乎可以解释一下,但我找不到任何其他具有“动态查找”一词的资源。
【问题讨论】:
-
您的 F# 示例是错误的。这不是为 x 分配一个新值,它实际上是在声明一个名为 x 的新变量,它将前一个变量隐藏在当前范围内。如果您将 x 声明为可变的,然后使用
<-分配给它,那么它的工作方式与 C# 相同。 -
@mydogisbox 的目的是,我正在做阴影,而不是 F# 中的赋值,以模仿纯粹的函数式语言。顺便说一句,我不是在将 F# 与 C# 进行比较,而是将 F# 与 R 进行比较,将 C# 与 R 进行比较。
-
我不确定如何回答这个问题,而不是简单地向您引用 R 的关于其实现词法作用域的文档。
-
@joran 所有 3 种语言都是词法范围
-
但是仅仅因为它们都声称是“词法作用域”并不意味着在实现上不会有一些小的差异。它们可能相似,但毕竟它们是不同的语言。
标签: c# r f# functional-programming closures