为什么有些基元有字节码而有些没有呢?

时间:2014-09-25 03:53:56

标签: r

我注意到当我在原始函数的某些上调用args时,字节代码也会显示出来。但在其他原语上,不会出现字节码。例如

args(length)
# function (x) 
# NULL
args(list)
# function (...) 
# NULL
# <bytecode: 0x44a0f38>

为什么?

起初我认为它可能与...论证有关,但以下反驳了该理论。

args(dim)
# function (x) 
# NULL
args(unclass)
# function (x) 
# NULL
# <bytecode: 0x44a0450>

让我感到困惑的是,字节码只出现在其中一些中,而不出现在其他中。我一直认为所有原语都是特殊的,并且它们都共享相同的属性&#34; (缺少更好的词,而不是实际的R属性)。

2 个答案:

答案 0 :(得分:9)

正如agstudy指出的那样,这与args如何打印事物有关。也就是说,args在其输出中是否包含字节码行并不是该函数是否是字节编译的可靠指示。比较:

args(writeLines)
## function (text, con = stdout(), sep = "\n", useBytes = FALSE) 
##   NULL

writeLines
## function (text, con = stdout(), sep = "\n", useBytes = FALSE) 
## {
##   if (is.character(con)) {
##     con <- file(con, "w")
##     on.exit(close(con))
##   }
##   .Internal(writeLines(text, con, sep, useBytes))
## }
## <bytecode: 0x000000001bf3aeb0>

我们可以比较args与标准功能打印的字节码行的打印。

arg_shows_bytecode <- function(fn)
{
  output <- capture.output(args(fn))
  grepl("^<bytecode", output[length(output)])
}

printing_shows_bytecode <- function(fn)
{
  output <- capture.output(print(fn))
  length(output) > 1 && grepl("^<bytecode", output[length(output) - 1])   
}

base_fns <- Filter(is.function, mget(ls(baseenv()), baseenv()))
yn_args <- vapply(base_fns, arg_shows_bytecode, logical(1))
yn_print <- vapply(base_fns, printing_shows_bytecode, logical(1))

值得注意的是,args显示字节码信息的所有函数都是原语。

head(base_fns[yn_args])
## $`%*%`
## function (x, y)  .Primitive("%*%")
## 
## $as.call
## function (x)  .Primitive("as.call")
## 
## $attr
## function (x, which, exact = FALSE)  .Primitive("attr")
## 
## $`attr<-`
## function (x, which, value)  .Primitive("attr<-")
## 
## $attributes
## function (obj)  .Primitive("attributes")
## 
## $`attributes<-`
## function (obj, value)  .Primitive("attributes<-")

相反的情况并非如此:args未显示字节码信息的一些基函数是基元;其他人不是。

yn_prim <- vapply(base_fns, is.primitive, logical(1))
table(yn_args, yn_print, yn_prim)
## , , yn_prim = FALSE
## 
##        yn_print
## yn_args FALSE TRUE
## FALSE       0  988
## TRUE        0    0
## 
## , , yn_prim = TRUE
## 
##        yn_print
## yn_args FALSE TRUE
## FALSE     119    0
## TRUE       63    0

所以编译了基础包中的非原始函数,但是args没有提到它。原始函数在打印时不显示字节码消息,只有在使用args调用时才会显示字节码消息。

答案 1 :(得分:1)

感谢您的报告。这种行为是无意的(一个错误,正如Hadley所说),它在内部不一致,因为字节码地址仅针对内置和特殊显示,并且仅当它们的形式位于.ArgsEnv时(它们也可以在{{1}中}})。现在修复了R-devel。错误报告最好直接导入R bugzilla(R-devel邮件列表也适用)。