3

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

4

2 回答 2

1

我不确定我是否完全理解你的问题,但也许这些例子有助于说明一个值的范围(但这些可能不是很好的例子!)但我强烈建议你阅读表达式的评估部分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
于 2013-04-29T14:40:56.387 回答
0

来自Scheme,我没有看到混乱。

例如,使用 chibi-scheme (R7RS):

$ chibi-scheme
> (define f (lambda () x))
WARNING: reference to undefined variable: x
> (define x 15)
> (f)
15
> (define x 20)
> (f)
20

对于任何兼容的 Scheme 版本应该是相同的(至少在 Guile 和 MIT/GNU Scheme 中工作)。REPL 可能与编译器不同,但即使您编写了上述内容并对其进行了编译,它也会使用符号表并在解析文件后解析引用。它仍然可以工作。

f具有对变量指定的内存位置的值的引用x。当您这样做f <- 15f <- 20您更新而不是参考或位置时。

我可能是错的(或错误地使用了技术术语),但我仍然觉得这并不奇怪。

于 2014-04-26T16:02:12.580 回答