【发布时间】:2017-03-28 07:09:30
【问题描述】:
我看到一些调用 C 代码的函数被描述为 primitive、internal、builtin 或 special。这些功能是什么?
【问题讨论】:
我看到一些调用 C 代码的函数被描述为 primitive、internal、builtin 或 special。这些功能是什么?
【问题讨论】:
这个问题将两个不同的概念混为一谈。 special 和 builtin 是由typeof 确定的三种函数类型中的两种(以及closures)。
来自R-ints, 1.5 Argument evaluation
作为一个特殊的/内置的与原始的或 .Internal:quote 是一个特殊的原语,+ 是内置的 原始的, cbind 是一个特殊的 .Internal 和 grep 是一个内置 。内部的。
如果函数调用 C 代码,内置/特殊是指在传递给 C 代码之前是否评估其参数。
来自R-lang, 2.1.7 Builtin objects and special forms
内置函数的所有参数都被评估和传递 到内部函数,按照按值调用, 而特殊函数将未计算的参数传递给 内部功能。
.Internal和.Primitive指的是用来调用C代码的接口。内部是标准方法,因为您可以在调用 C 代码之前检查 R 代码中的参数。 Primitive 性能更高,但不允许在函数中使用任何 R 代码。
来自R-ints, 2 .Internal vs .Primitive
在构建时编译成 R 的 C 代码可以直接在 什么被称为原语或通过 .Internal 接口,其中 除了语法之外,它与 .External 接口非常相似。更多的 准确地说,R 维护了一个 R 函数名称表和 要调用的相应 C 函数,按照惯例,所有函数都开始 使用“do_”并返回 SEXP。此表(文件中的 R_FunTab src/main/names.c) 还指定函数的参数数量 是必需的还是允许的,无论论点是否是 在调用之前评估,以及函数是否为“内部” 从某种意义上说,它必须通过 .Internal 接口访问, 或直接可访问,在这种情况下,它在 R 中打印为 .原始的。
使用 .Internal() 包裹在闭包中的函数通常是 首选,因为这确保了命名和默认的标准处理 论据。
但是,出于方便和效率的原因(如 使用 .Internal 接口的一些开销 函数闭包),原始函数是异常,可以 可以直接访问。
【讨论】:
r-faq,那么获得社区满意的答案很重要。我从其他答案中得到了很多分数。
.Primitive 对象。你能扩大差异吗?我尝试过寻找解释,并在 R 中进行实验,但不明白。例如,`+` 被定义为 函数,而 `(` 和 return 不是(尽管可以调用)。
is.function(`(`) 和is.function(return)。不知道为什么他们的打印方法只是说.Primitive()。
.Primitive(…) 返回一个函数。因此,我不明白(例如)c 是如何工作的:例如,如果我复制它的定义并将其分配给不同的变量,则结果不起作用:x = function(...) .Primitive("c"); x(1, 2) 返回.Primitive("c")。相比之下,如果我直接定义y = .Primitive("c"),它就可以工作。那么c 是做什么的呢?此外,x 和 c 实际上在控制台中的打印方式略有不同。