Reputation: 121077
From ?builtins
:
builtins(TRUE)
returns an unsorted list of the names of internal functions, that is those which can be accessed as.Internal(foo(args ...))
for foo in the list.
I don't understand which functions are being returned.
I thought it would be all the closure functions in the base package that call .Internal()
.
However, the two sets don't match up.
base_objects <- mget(
ls(baseenv(), all.names = TRUE),
envir = baseenv()
)
internals <- names(
Filter(
assertive.types::is_internal_function,
base_objects
)
)
builtins_true <- builtins(internal = TRUE)
c(
both = length(intersect(internals, builtins_true)),
internals_not_builtins_true = length(setdiff(internals, builtins_true)),
builtins_true_not_internals = length(setdiff(builtins_true, internals))
)
## both internals_not_builtins_true builtins_true_not_internals
## 288 125 226
I also thought that it might be the values listed in src/main/names.c
in R's source code, and there definitely seems to be some overlap with this, but it isn't exactly this list of values.
What is builtins()
doing when you pass internal = TRUE
?
Upvotes: 2
Views: 83
Reputation: 121077
After more digging, it seems that the list of functions is everything in the R_FunTab[]
object in src/main/names.c
where the second digit of the eval
column is 1
.
Here's a script to retrieve them.
library(stringi)
library(magrittr)
library(dplyr)
names.c <- readLines("https://raw.githubusercontent.com/wch/r-source/56a1b08b7282c5488acb71ee244098f4fd94f7c7/src/main/names.c")
fun_tab <- names.c[92:974] %>%
stri_replace_all_regex("^\\{", "") %>%
stri_replace_all_fixed("{PP", "PP") %>%
stri_replace_all_fixed("}},", "") %>%
stri_replace_all_fixed("\\t", "")
funs <- read.csv(text = fun_tab, header = FALSE, comment.char = "/")
cols <- names.c[86] %>%
stri_sub(4) %>%
stri_split_regex("\\t+") %>%
extract2(1) %>%
stri_trim()
colnames(funs) <- cols
funs$eval <- formatC(funs$eval, width = 3, flag = "0")
# Internal fns have 2nd digit of eval col == 1. See names.c[62:71]
internals <- funs %>% filter_(~ substring(eval, 2, 2) == 1)
I see slight differences when examining
setdiff(internals$printname, builtins(TRUE))
setdiff(builtins(TRUE), internals$printname)
For example builtins(TRUE)
doesn't include shell.exec()
if you aren't running Windows; mem.limits()
was only recently removed from the devel branch of R, so it shows up in builtins(TRUE)
for the current release version of R.
Upvotes: 1
Reputation: 176648
Stibu's comment is a specific example of the general problem. ?builtins
says that it fetches the names of the objects it returns directly from the symbol table (this is the C symbol table).
And builtins(TRUE)
returns all the built-in objects callable via .Internal
. That, however, doesn't mean there must be any function that calls .Internal(foo(args, ...))
for any foo
.
Stibu gave one example: the internal function may not be called by an R function with the same name, as is the case for many generic functions where the default method calls .Internal
.
Another example is something like .addCondHands
and .addRestart
, which are called by withCallingHandlers
and withRestarts
, respectively.
It's also possible that one R function calls multiple .Internal
functions. I don't know of an example of that off the top of my head though.
Upvotes: 2