(R-ints.info).Internal vs .Primitive


Next: Internationalization in the R sources Prev: R Internal Structures Up: Top
Enter node , (file) or (file)node

2 '.Internal' vs '.Primitive'
*****************************

C code compiled into R at build time can be called directly in what are
termed _primitives_ 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'.
This table ('R_FunTab' in file 'src/main/names.c') also specifies how
many arguments to a function are required or allowed, whether or not the
arguments are to be evaluated before calling, 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'.

   Functions using '.Internal()' wrapped in a closure are in general
preferred as this ensures standard handling of named and default
arguments.  For example, 'grep' is defined as

     grep <-
     function (pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE,
              fixed = FALSE, useBytes = FALSE, invert = FALSE)
     {
         if (!is.character(x)) x <- structure(as.character(x), names = names(x))
         .Internal(grep(as.character(pattern), x, ignore.case, value,
                        perl, fixed, useBytes, invert))
     }

and the use of 'as.character' allows methods to be dispatched (for
example, for factors).

   However, for reasons of convenience and also efficiency (as there is
some overhead in using the '.Internal' interface wrapped in a function
closure), the primitive functions are exceptions that can be accessed
directly.  And of course, primitive functions are needed for basic
operations--for example '.Internal' is itself a primitive.  Note that
primitive functions make no use of R code, and hence are very different
from the usual interpreted functions.  In particular, 'formals' and
'body' return 'NULL' for such objects, and argument matching can be
handled differently.  For some primitives (including 'call', 'switch',
'.C' and '.subset') positional matching is important to avoid partial
matching of the first argument.

   The list of primitive functions is subject to change; currently, it
includes the following.

  1. "Special functions" which really are _language_ elements, but
     implemented as primitive functions:

          {       (         if     for      while  repeat  break  next
          return  function  quote  switch

  2. Language elements and basic _operator_s (i.e., functions usually
     _not_ called as 'foo(a, b, ...)') for subsetting, assignment,
     arithmetic, comparison and logic:

                         [    [[    $    @
          <-   <<-  =    [<-  [[<-  $<-  @<-

          +    -    *    /     ^    %%   %*%  %/%
          <    <=   ==   !=    >=   >
          |    ||   &    &&    !

     When the arithmetic, comparison and logical operators are called as
     functions, any argument names are discarded so positional matching
     is used.

  3. "Low level" 0- and 1-argument functions which belong to one of the
     following groups of functions:

       a. Basic mathematical functions with a single argument, i.e.,

               abs     sign    sqrt
               floor   ceiling

               exp     expm1
               log2    log10   log1p
               cos     sin     tan
               acos    asin    atan
               cosh    sinh    tanh
               acosh   asinh   atanh
               cospi   sinpi   tanpi

               gamma   lgamma  digamma trigamma

               cumsum  cumprod cummax  cummin

               Im  Re  Arg  Conj  Mod

          'log' is a primitive function of one or two arguments with
          named argument matching.

          'trunc' is a difficult case: it is a primitive that can have
          one or more arguments: the default method handled in the
          primitive has only one.

       b. Functions rarely used outside of "programming" (i.e., mostly
          used inside other functions), such as

               nargs          missing        on.exit        interactive
               as.call        as.character   as.complex     as.double
               as.environment as.integer     as.logical     as.raw
               is.array       is.atomic      is.call        is.character
               is.complex     is.double      is.environment is.expression
               is.finite      is.function    is.infinite    is.integer
               is.language    is.list        is.logical     is.matrix
               is.na          is.name        is.nan         is.null
               is.numeric     is.object      is.pairlist    is.raw
               is.real        is.recursive   is.single      is.symbol
               baseenv        emptyenv       globalenv      pos.to.env
               unclass        invisible      seq_along      seq_len

       c. The programming and session management utilities

               browser  proc.time  gc.time tracemem retracemem untracemem

  4. 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<-
                      storage.mode<-

     Note that optimizing 'NAMED = 1' is only effective within a
     primitive (as the closure wrapper of a '.Internal' will set 'NAMED
     = NAMEDMAX' when the promise to the argument is evaluated) and
     hence replacement functions should where possible be primitive to
     avoid copying (at least in their default methods).

  5. The following functions are primitive for efficiency reasons:

          :           ~           c           list
          call        expression  substitute
          UseMethod   standardGeneric
          .C          .Fortran   .Call        .External
          round       signif      rep         seq.int

     as well as the following internal-use-only functions

          .Primitive      .Internal
          .Call.graphics  .External.graphics
          .subset         .subset2
          .primTrace      .primUntrace
          lazyLoadDBfetch

   The multi-argument primitives
     call       switch
     .C         .Fortran   .Call       .External

intentionally use positional matching, and need to do so to avoid
partial matching to their first argument.  They do check that the first
argument is unnamed or for the first two, partially matches the formal
argument name.  On the other hand,

     attr       attr<-     browser     rememtrace substitute  UseMethod
     log        round      signif      rep        seq.int

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

   All the one-argument primitives check that if they are called with a
named argument that this (partially) matches the name given in the
documentation: this is also done for replacement functions with one
argument plus 'value'.

   The net effect is that argument matching for primitives intended for
end-user use _as functions_ is done in the same way as for interpreted
functions except for the six exceptions where positional matching is
required.

Special primitives
Special internals
Prototypes for primitives
Adding a primitive

automatically generated by info2www version 1.2.2.9