下一个： R coding standards, 上一个： R Internal Structures, 上层： Top

`.Internal`

vs `.Primitive`

C code compiled into R at build time can be called “directly” or
via the `.Internal`

interface, which is very similar to the
`.External`

interface except in syntax. More precisely, R
maintains a table of R function names and corresponding C functions to
call, which by convention all start with ``do_`' and return a SEXP.
Via this table (`R_FunTab`

in file `src/main/names.c`) one can
also specify how many arguments to a function are required or allowed,
whether the arguments are to be evaluated before calling or not, and
whether the function is “internal” in the sense that it must be
accessed via the `.Internal`

interface, or directly accessible in
which case it is printed in R as `.Primitive`

.

R's functionality can also be extended by providing corresponding C code and adding to this function table.

In general, all such functions use `.Internal()`

as this is safer
and in particular allows for transparent handling of named and default
arguments. For example, `axis`

is defined as

axis <- function(side, at = NULL, labels = NULL, ...) .Internal(axis(side, at, labels, ...))

However, for reasons of convenience and also efficiency (as there is
some overhead in using the `.Internal`

interface wrapped in a
function closure), there are exceptions which can be accessed directly.
Note that these functions make no use of R code, and hence are very
different from the usual interpreted functions. In particular,
`args`

, `formals`

and `body`

return `NULL`

for such
objects, and argument matching is purely positional (with empty
positions being dropped).

The list of these “primitive” functions is subject to change: currently, it includes the following.

- “Special functions” which really are
*language*elements, however exist as “primitive” functions in R:{ ( if for while repeat break next return function quote on.exit

- Basic
*operator*s (i.e., functions usually*not*called as`foo(a, b, ...)`

) for subsetting, assignment, arithmetic and logic. These are the following 1-, 2-, and N-argument functions:[ [[ $ @ <- <<- = [<- [[<- $<- + - * / ^ %% %*% %/% < <= == != >= > | || & && !

- “Low level” 0- and 1-argument functions which belong to one of the
following groups of functions:
- Basic mathematical functions with a single argument, i.e.,
sign abs floor ceiling trunc sqrt exp cos sin tan acos asin atan cosh sinh tanh acosh asinh atanh cumsum cumprod cummax cummin Im Re Arg Conj Mod

Note however that the R function

`log`

has an optional named argument`base`

, and therefore is defined aslog <- function(x, base = exp(1)) { if(missing(base)) .Internal(log(x)) else .Internal(log(x, base)) }

in order to ensure that

`log(x = pi, base = 2)`

is identical to`log(base = 2, x = pi)`

. - Functions rarely used outside of “programming” (i.e., mostly used
inside other functions), such as
nargs missing interactive is.

*xxx*.Primitive .Internal globalenv baseenv emptyenv pos.to.env unclass seq_along seq_len(where

*xxx*stands for 27 different notions, such as`function`

,`vector`

,`numeric`

, and so forth, but not`is.loaded`

). - The programming and session management utilities
debug undebug browser proc.time gc.time

- Basic mathematical functions with a single argument, i.e.,
- The following basic replacement and extractor functions
length length<- class class<- oldClass oldCLass<- attr attr<- attributes attributes<- names names<- dim dim<- dimnames dimnames<- environment<- levels<-

Note that optimizing

`NAMED = 1`

is only effective within a primitive (as the closure wrapper of a`.Internal`

will set`NAMED = 2`

on the argument) and hence replacement functions should where possible be primitive to avoid copying (at least in their default methods). - The following few N-argument functions are “primitive” for
efficiency reasons:
: ~ c list call as.call as.character expression substitute as.environment UseMethod invisible standardGeneric .C .Fortran .Call .External .Call.graphics .External.graphics .subset .subset2 .primTrace .primUntrace tracemem retracemem untracemem rep seq.int

`rep`

and`seq.int`

manage their own argument matching and so do work in the standard way.