R 如何调用'function'函数?
我试图调用函数R 如何调用'function'函数?,r,R,我试图调用函数`function`来定义R代码中的函数 众所周知™️, `function`是一个.Primitive,当用户使用常规语法,即 mean1 = function (x, ...) base::mean(x, ...) 但是没有什么能阻止我直接调用那个原语。至少我是这么想的。我可以直接调用其他原语(甚至可以重新定义它们;例如,在疯狂的时刻)。所以这在原则上是可能的 但是我不能让它为`函数`工作。以下是我尝试过的: # Works mean2 = as.function(c(for
`function`
来定义R代码中的函数
众所周知™️, `function`
是一个.Primitive
,当用户使用常规语法,即
mean1 = function (x, ...) base::mean(x, ...)
但是没有什么能阻止我直接调用那个原语。至少我是这么想的。我可以直接调用其他原语(甚至可以重新定义它们;例如,在疯狂的时刻)。所以这在原则上是可能的
但是我不能让它为`函数`
工作。以下是我尝试过的:
# Works
mean2 = as.function(c(formals(mean), quote(mean(x, ...))))
# Works
mean3 = eval(call('function', formals(mean), quote(mean(x, ...))))
# Error: invalid formal argument list for "function"
mean4 = `function`(formals(mean), quote(mean(x, ...)))
mean3
特别有效的事实向我表明mean4
应该有效。但事实并非如此。为什么?
我检查了R源代码中`function`
原语的定义。我看到它调用,这确保了每个参数都是一个符号,但这失败了。但它为什么要检查这个,这意味着什么
最重要的是:有没有直接调用`函数`
原语的方法
只是想澄清一下:有一些琐碎的解决办法(这个问题列出了两个,至少还有第三个)。但我想了解这是如何工作的。这是因为
函数是一种特殊的原语:
typeof(`function`)
#> [1] "special"
参数没有计算,因此您实际上传递了quote(formals(mean))
而不是formals(mean)
的值。我不认为有一种方法可以直接调用函数
,而不使用求值技巧,除了一个空的形式列表,它只是空的
,,为了完整起见,莱昂内尔的回答暗示了一种调用函数
的方法。不幸的是,它相当有限,因为除了NULL
,我们无法传递任何参数定义:
mean5 = `function`(NULL, mean(x, ...))
formals(mean5) = formals(mean)
(注意正文周围没有引用!)
这当然是完全不实际的(并且形式在对源代码进行了一点挖掘之后,下面是一些观察结果:
实际的函数创建是由。这是由function(){}
调用的,由as.function.default()
和.Primitive(“函数”)
调用的(也称为`function`
)
as.function.default()
被路由到,但是,它直接在上面几行构造这些形式
正如您所指出的,调用CheckFormals()
的另一个地方是do\u function()
内部。但是,我认为do\u function()
不会被以外的任何东西调用。Primitive(“function”)
,因此这是CheckFormals()的唯一情况根据用户的输入调用
CheckFormals()
确实正确验证了pairlist
对象
通过使用inline::cfunction
inline::cfunction( c(x="ANY"),
'Rprintf("is list?: %d\\nTag1 OK?: %d\\nTag2 OK?: %d\\nTag3 NULL?: %d\\n",
isList(x), TYPEOF(TAG(x)) == SYMSXP, TYPEOF(TAG(CDR(x))) == SYMSXP,
CDR(CDR(x)) == R_NilValue); return R_NilValue;' )( formals(mean) )
# is list?: 1
# Tag1 OK?: 1
# Tag2 OK?: 1
# Tag3 NULL?: 1
因此,在将形式(means)
传递给原语(“函数”)
和通过do\u function()
将其转发给CheckFormals()
之间的某个地方,参数失去了其有效性。(我不太了解R源代码,无法告诉您这是如何发生的。)然而,由于do\u function()
仅由.Primitive(“function”)
调用,在其他任何示例中都不会遇到这种情况。我实际上尝试了引用形式(以及使用alist
),但正如您所注意到的,这也不起作用。typeof(`for`)
也是“特殊的”,但是为
`手动调用``是有效的。是的,因为为
调用`需要一个符号和两个表达式,其中有解析器语法。没有显式的解析器语法来创建成对列表文字,这就是函数()
takes.确实如此。我刚刚发现,您可以使用手动生成的pairlist
调用它-但再一次只能间接调用,因为正如您所说,没有pairlist
文本语法。重复的(我发誓我后来发现了)相关:@Moody在上面链接中的回答指出,它可以直接作为函数调用,本质上做的是函数的功能。@ArtemSokolov…当然,但这正是我的意思3
定义的功能。我只是好奇为什么它似乎不起作用。很抱歉误解。请看下面我的回答。哟就你的推理而言,你是正确的。我认为拼图中缺少的部分是名称中函数的声明。c
:与你自己的c函数不同,do\u函数
不会用求值的参数调用;相反,它会用未求值的参数调用,因此传递的不是成对列表,这是一个引用的表达式,它的计算结果将是成对列表。@KonradRudolph:你认为这是预期的行为吗?既不是Do\u function
,也不是`function`
,也不是.Primitive(“function”)
在内部使用(由grep
-ing源代码确定).那么,如果用户不能直接调用它,那么该函数是为谁设计的?函数.Primitive(“函数”)当您将解析器创建的对函数的调用计算为解释器创建的函数对象时,将调用。请注意,这两种对象打印相同,可能会造成混淆。请检查引号(函数(foo,bar)NULL)之间的差异
和未加引号的版本。您还可以使用.Internal(inspect(quote(function(foo,bar)NULL))
验证解析器是否在调用函数时正确创建了形式列表。