c# - Closure 的 R 实现不同于其他函数式语言,这使得它表现得像 C# 等命令式语言?

标签 c# r f# functional-programming closures

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 中定义似乎解释了一下,但我找不到任何其他具有术语“动态查找”的资源。

最佳答案

我不确定我是否完全理解您的问题,但也许这些示例有助于说明如何确定值的范围(但这些可能不是很好的示例!)但我强烈建议您阅读 evaluation of expressions 部分R 语言定义(事实上我应该再去读一遍):

# Define default value for x in function definition
f <- function( x = 15 ) x
f()
#[1] 15

# Assign value to x in .GlobalEnv
x <- 20

# But x is found in the environment of the function call because we already defined it there, so value we assigned inside the function is returned
f()
#[1] 15

# Now we pass an object, x to the function which causes it to search up the calling stack for an 'object' called x
f(x)
#[1] 20

# In this example we use 'get' to search for the object. In the help page it states:
# The default is to search from the current environment of the call to 'get'
f <- function() get( "x" )
f()
[1] 20

# But we can specify an environment to search in
# In this case we specify an environment where x was not defined
# and it is not found
f<- function() { pos <- sys.nframe()+1 ; get("x" ,  envir = as.environment(pos) ) }
f()
#Error in get("x", envir = as.environment(2)) : object 'x' not found

关于c# - Closure 的 R 实现不同于其他函数式语言,这使得它表现得像 C# 等命令式语言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16280761/

相关文章:

c# - 将带有指针的 C++ DLL 导入 C#

c# - 如何快速将两个字节添加到字节数组中?

c# - 非常简单的网络服务 : take inputs, 电子邮件结果

从 R 中的 CSV 文件读取 `...` 中定义的函数输入值

generics - 为什么这个通用成员约束不被理解

deployment - 假 FtpHelper 用法

C# Xamarin 使用了错误的 If 子句?

r - 查找并删除缺失数据大于 5% 的行

r - R 中的 nls() 函数

日期范围的 F# 生成器?