2017-09-25 53 views
2

我注意到R函数仅在函数体中计算特定参数时检查缺少的参数。为什么R在通话开始时不检查缺失的参数?

例子:

f <- function(x, y) { 
    Sys.sleep(3) 
    return(x + y) 
} 
f(1) 

功能需要3秒的失败,并且在函数调用的开始报告,而这名失踪的说法。这种实现的优点是什么?

编辑:

我所知道的力()和失踪()。我想知道在评估之前立即丢失()参数的好处,而不是在函数调用的开始处。这样的实施有没有必要的理由?

作为一个人为的例子

f2 <- function() { 
    Sys.sleep(3) 
} 

f <- function(x, y) { 
    if (missing(y)) stop("y missing") 
    print(x) 
} 

f(1, f2()) 

的“昂贵”呼叫到f2()仍然由惰性求避免,但其missingness可以在不评价进行检查。

EDIT2:

我想你可以争辩说,它给出了生成的默认值更大的灵活性,另一人为的例子,如果参数检查是在函数调用立即进行

f <- function(x, y = 1:3) { 
    if (missing(x)) { 
     x <- y 
    } 
    x 
} 

f() 

这样的代码会失败。不过,这段代码最好写成function(x = y, y = 1:3)。虽然我猜这样的功能会被一些不重要的代码库所使用,现在改变行为会比它的价值更麻烦。

+1

R是照本宣科,而不是编译语言。许多其他事物也只在运行时才会失败,例如类型安全问题。当我[运行你的示例脚本](http://rextester.com/QWSQVQ35038)我肯定会回来错误反馈告诉我发生了什么。 –

+0

抱歉,我会编辑问题以清楚说明。我指出的事实是,它不会失败,直到变量y实际上在函数的主体中被计算,我没有看到任何理由为什么在函数调用开始时没有检查参数的缺失。 – shians

+2

懒惰评估是一项功能。它使得许多呼叫更快。 – Roland

回答

3

R使用懒惰评估。也就是说,直到 它们是必需的,函数的参数才会被评估。这可以节省时间和内存,如果事实证明 参数不是必需的。 在极其罕见的情况下,应评估的东西没有得到评估。 您可以使用force来解决懒惰问题。

伯恩斯,帕特里克。 “The R Inferno”。 http://www.burns-stat.com/pages/Tutor/R_inferno.pdf

所以,这下面的代码将失败更快:

f <- function(x, y) { 
force(y) 
Sys.sleep(3) 
return(x + y) 
} 
f(1) 

f <- function(x, y) { 
    if(missing(y)) stop("missing y") 
    Sys.sleep(3) 
    return(x + y) 
} 
f(1) 
+0

我的问题真的是为什么它的实现,所以你必须手动进行缺失检查,但我想知道为什么自动检查在函数的开始不是默认行为。我想我正在寻找任何与此选择有关的邮件列表讨论。 – shians

+0

同样,这是一个功能。有时候你想方便地调用缺少参数的函数。许多功能都是以这种方式实现的。 – Roland

+0

您是否介意将这些众多功能中的一个功能作为答案发布,并说明为什么有必要? – shians