2014-09-25 10 views
12

Ich habe bemerkt, dass, wenn ich args auf einige der primitiven Funktionen aufrufen, Byte-Codes auch angezeigt werden. Aber auf anderen Primitiven erscheint kein Byte-Code. Zum BeispielWarum haben einige Primitive Byte-Codes und andere nicht?

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

Warum ist das?

Zuerst dachte ich, es könnte mit dem ... Argument zusammenhängen, aber das folgende widerlegt diese Theorie.

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

Es ist verwirrend für mich, dass ein Byte-Code nur in einigen von diesen und nicht in anderen angezeigt wird. Ich habe immer den Eindruck gehabt, dass alle Primitiven speziell sind und dass sie alle die gleichen "Attribute" teilen (aus Mangel an einem besseren Wort, nicht die tatsächlichen R-Attribute).

+0

Ich denke, die Druckdifferenz ist aus historischen Gründen. 'args' wird eher für den Konsolendruck verwendet, vielleicht kann man' formals' verwenden, um eine kohärentere Ausgabe zu erhalten. – agstudy

Antwort

9

Wie agstudy bemerkt, ist dies eine Kuriosität im Zusammenhang mit wie args druckt Dinge. Das heißt, ob args eine Bytecode-Zeile in seiner Ausgabe enthält, ist kein zuverlässiger Indikator dafür, ob die Funktion Byte-kompiliert wurde oder nicht. vergleichen:

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> 

Wir Druck einer Bytecode-Linie für args vs. Standardfunktionsdruck vergleichen.

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)) 

Es ist erwähnenswert, dass alle Funktionen, bei denen args Bytecode Informationen zeigt Primitive sind.

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<-") 

Die Umkehrung gilt nicht: einige Basisfunktionen, wo args nicht Bytecode Informationen sind Primitiven nicht zeigen; andere sind nicht.

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 

So nicht-primitive Funktionen im Basispaket sind alle zusammengestellt, aber args es nicht erwähnen. Primitive Funktionen zeigen beim Drucken keine Bytecode-Meldung und zeigen nur manchmal eine Bytecode-Nachricht, wenn sie mit Argumenten aufgerufen werden.

+3

Einfachere Erklärung: Dies ist ein Fehler in 'args()'. Es sollte niemals den Bytecode-Kompilierungsstatus anzeigen, da dies keine Eigenschaft der Argumentliste einer Funktion ist. – hadley

1

Danke für den Bericht. Dieses Verhalten ist unbeabsichtigt (ein Fehler, wie Hadley sagt), es ist intern nicht konsistent, da die Bytecode-Adresse nur für Builtins und Specials angezeigt wird und nur wenn ihre Formals in .ArgsEnv sind (sie können auch in .GenericArgsEnv sein). Jetzt in R-devel behoben. Fehlerberichte sind am besten direkt in R Bugzilla (R-devel Mailing-Liste funktioniert auch).

Verwandte Themen