# The R.lua module

For the getting started guide, see Introduction to `luajr`.

## Introduction

This vignette is for advanced R users who know how to use R’s API from C code. If you normally use R without C, this vignette may not make a lot of sense to you. If you use the Rcpp or cpp11 packages to interface C++ code with R, but have not used R’s C API directly, this vignette may not make sense to you either. Just a warning!

The luajr package ships with two Lua modules included. The more commonly-used module is `luajr.lua`, which offers convenience and higher-level interaction with R. That module is described in the vignette The luajr.lua module.

But, if you need lower-level access to R’s internals from Lua, then `R.lua` may be helpful to you. The `R.lua` module provides access to R’s C API from Lua. If you understand what each element of the following C code does:

    SEXP s = PROTECT(Rf_allocVector(VECSXP, 3));

then you may find this vignette helpful. If not, you will need to thoroughly consult the Writing R Extensions manual before proceeding, because this vignette assumes you are already familiar with R’s C API.

## Loading R.lua

Any Lua state that has been opened through the luajr package automatically loads the `luajr.lua` module, but the `R.lua` module needs to be loaded explicitly before use. The `R.lua` module can be loaded in Lua code like so:

    R = require "R"

The above line of Lua code opens the `R.lua` module and loads it into a global Lua variable `R`. Once that line has been executed in a Lua state, you can start to use the R functions and types that are part of the module. Of course, you can assign the module to a local variable instead.

## R.sexp

R’s C API represents R values using the type `SEXP`, meaning “S expression”. The `SEXP` type is a pointer to an opaque C struct `SEXPREC` – see R Internals for full details. Within Lua code, `R.sexp` is an alias for the `SEXP` type (through LuaJIT’s ctype mechanism), which means you can use Lua variables of type `R.sexp` to pass to R’s API functions.

## Functions

`R.lua` exposes some (but not all) of R’s C API functions.

The naming of R’s C API functions is all over the place. Some functions have no prefix, others have the prefix `R_`, and still others have the prefix `Rf_`, with no obvious pattern. Function names can be UPPER_CASE, lower_case, camelCase or TitleCase. It can be confusing.

`R.lua` drops all `R_` and `Rf_` prefixes because the module is typically loaded into a table named `R`, so `R.Rf_allocVector` would seem redundant (instead it is `R.allocVector`). But the case of the function name is kept as-is for consistency with the C API, and when there is a familiar C macro that maps to a function, the case of the macro is preferred (for example, `PROTECT` in C is a macro mapping to the function `Rf_protect`; the corresponding `R.lua` function is named `R.PROTECT`, not `R.protect`).

Assuming the `R.lua` module has been loaded into a table named `R`, you can use the following R API functions:

Lua name | corresponding C signature
--- | ---
`R.allocVector` | `SEXP Rf_allocVector(SEXPTYPE type, R_xlen_t length)`
`R.CHAR` | `const char* R_CHAR(SEXP x)`
`R.CheckUserInterrupt` | `void R_CheckUserInterrupt(void)`
`R.classgets` | `SEXP Rf_classgets(SEXP vec, SEXP klass)`
`R.coerceVector` | `SEXP Rf_coerceVector(SEXP v, SEXPTYPE type)`
`R.cons` | `SEXP Rf_cons(SEXP car, SEXP cdr)`
`R.copyMostAttrib` | `void Rf_copyMostAttrib(SEXP inp, SEXP ans)`
`R.DATAPTR_RO` | `const void* DATAPTR_RO(SEXP x)`
`R.defineVar` | `void Rf_defineVar(SEXP symbol, SEXP value, SEXP rho)`
`R.dimgets` | `SEXP Rf_dimgets(SEXP vec, SEXP val)`
`R.dimnamesgets` | `SEXP Rf_dimnamesgets(SEXP vec, SEXP val)`
`R.duplicate` | `SEXP Rf_duplicate(SEXP s)`
`R.DUPLICATE_ATTRIB` | `void DUPLICATE_ATTRIB(SEXP to, SEXP from)`
`R.eval` | `SEXP Rf_eval(SEXP e, SEXP rho)`
`R.ExternalPtrAddr` | `void* R_ExternalPtrAddr(SEXP s)`
`R.findFun` | `SEXP Rf_findFun(SEXP symbol, SEXP rho)`
`R.FlushConsole` | `void R_FlushConsole(void)`
`R.getAttrib` | `SEXP Rf_getAttrib(SEXP vec, SEXP name)`
`R.GetOption1` | `SEXP Rf_GetOption1(SEXP tag)`
`R.getRegisteredNamespace`* | `SEXP R_getRegisteredNamespace(const char* name)` added in 4.6.0
`R.getVarEx`* | `SEXP R_getVarEx(SEXP sym, SEXP rho, Rboolean inherits, SEXP ifnotfound)` added in 4.5.0
`R.inherits` | `Rboolean Rf_inherits(SEXP s, const char* name)`
`R.install` | `SEXP Rf_install(const char* name)`
`R.INTEGER` | `int* INTEGER(SEXP x)`
`R.isObject` | `Rboolean Rf_isObject(SEXP s)`
`R.lcons` | `SEXP Rf_lcons(SEXP car, SEXP cdr)`
`R.LOGICAL` | `int* LOGICAL(SEXP x)`
`R.lsInternal3` | `SEXP R_lsInternal3(SEXP env, Rboolean all, Rboolean sorted)`
`R.MakeExternalPtr` | `SEXP R_MakeExternalPtr(void *p, SEXP tag, SEXP prot)`
`R.mkChar` | `SEXP Rf_mkChar(const char* name)`
`R.mkCharLen` | `SEXP Rf_mkCharLen(const char* name, int len)`
`R.namesgets` | `SEXP Rf_namesgets(SEXP vec, SEXP val)`
`R.NewEnv`* | `SEXP R_NewEnv(SEXP enclos, int hash, int size)` added in 4.1.0
`R.ParentEnv`* | `SEXP R_ParentEnv(SEXP x)` added in 4.5.0
`R.PreserveObject` | `void R_PreserveObject(SEXP object)`
`R.PrintValue` | `void Rf_PrintValue(SEXP s)`
`R.PROTECT` | `SEXP Rf_protect(SEXP s)`
`R.RAW` | `Rbyte* RAW(SEXP x)`
`R.ReadConsole` | `int R_ReadConsole(const char* prompt, unsigned char* buf, int buflen, int hist)`
`R.REAL` | `double* REAL(SEXP x)`
`R.ReleaseObject` | `void R_ReleaseObject(SEXP object)`
`R.removeVarFromFrame` | `void R_removeVarFromFrame(SEXP name, SEXP env)`
`R.ScalarInteger` | `SEXP Rf_ScalarInteger(int x)`
`R.ScalarLogical` | `SEXP Rf_ScalarLogical(int x)`
`R.ScalarReal` | `SEXP Rf_ScalarReal(double x)`
`R.ScalarString` | `SEXP Rf_ScalarString(SEXP x)`
`R.SET_STRING_ELT` | `void SET_STRING_ELT(SEXP x, R_xlen_t i, SEXP v)`
`R.SET_TAG` | `void SET_TAG(SEXP x, SEXP y)`
`R.SET_VECTOR_ELT` | `SEXP SET_VECTOR_ELT(SEXP x, R_xlen_t i, SEXP v)`
`R.setAttrib` | `SEXP Rf_setAttrib(SEXP vec, SEXP name, SEXP val)`
`R.SHALLOW_DUPLICATE_ATTRIB` | `void SHALLOW_DUPLICATE_ATTRIB(SEXP to, SEXP from)`
`R.STRING_ELT` | `SEXP STRING_ELT(SEXP x, R_xlen_t i)`
`R.STRING_PTR_RO` | `const SEXP* STRING_PTR_RO(SEXP x)`
`R.TAG` | `SEXP TAG(SEXP e)`
`R.type2char` | `const char* Rf_type2char(SEXPTYPE t)`
`R.TYPEOF` | `int TYPEOF(SEXP x)`
`R.UNPROTECT` | `void Rf_unprotect(int l)`
`R.VECTOR_ELT` | `SEXP VECTOR_ELT(SEXP x, R_xlen_t i)`

* Entries marked with an asterisk were not present in R 4.0.0 (the minimum R version that luajr supports), but were added in later versions (as described in the table). However, they will work with any version of R (from 4.0.0 onward) because luajr implements backwards-compatible versions of these functions.

In addition to the functions above, the `R.lua` module provides some convenience functions to wrap some helpful operations.

`R.length(x)`

Returns the length of `SEXP x` as a Lua number. This is a wrapper for `Rf_xlength()` that converts the result from R’s 64-bit length type to a Lua number. You can use this anywhere you would normally use `Rf_length()` or `Rf_xlength()` in C.

`R.type_string(x)`

Returns the SEXP type of `SEXP x` as a Lua string. This is a wrapper for `Rf_type2char(TYPEOF(x))`.

`R.set_parent(env, parent)`

Sets the parent environment of `SEXP env`, an `ENVSXP`, to the `ENVSXP` `parent`. This calls into R’s `parent.env<-` function because the R C API does not currently provide a setter for environment parents.

## Constants

Common R constants are exposed as follows:

Lua name | C source
--- | ---
`R.TRUE` | `1`
`R.FALSE` | `0`
`R.NilValue` | `R_NilValue`
`R.NA_LOGICAL` | `R_NaInt`
`R.NA_INTEGER` | `R_NaInt`
`R.NA_REAL` | `R_NaReal`
`R.NA_STRING` | `R_NaString`
`R.UnboundValue` | `R_UnboundValue`
`R.MissingArg` | `R_MissingArg`
`R.GlobalEnv` | `R_GlobalEnv`
`R.EmptyEnv` | `R_EmptyEnv`
`R.BaseEnv` | `R_BaseEnv`
`R.BlankString` | `R_BlankString`
`R.NamesSymbol` | `R_NamesSymbol`
`R.ClassSymbol` | `R_ClassSymbol`
`R.DimSymbol` | `R_DimSymbol`
`R.DimNamesSymbol` | `R_DimNamesSymbol`
`R.RowNamesSymbol` | `R_RowNamesSymbol`
`R.NamespaceRegistry` | `R_NamespaceRegistry`

In addition to the above, there is also a variable `R.version` that holds the current R version as an integer in the form `MMmmpp` (MM = major, mm = minor, pp = patch). For example, R 4.6.0 is `040600` and R 4.0.5 is `040005`.

The R type codes (`SEXPTYPE`s) are also exposed as Lua numbers. These correspond to the values returned by `R.TYPEOF(x)`:

Lua name | Value | Description
--- | --- | ---
`R.NILSXP` | 0 | NULL
`R.SYMSXP` | 1 | symbols
`R.LISTSXP` | 2 | pairlists
`R.CLOSXP` | 3 | closures
`R.ENVSXP` | 4 | environments
`R.PROMSXP` | 5 | promises
`R.LANGSXP` | 6 | language objects
`R.SPECIALSXP` | 7 | special functions
`R.BUILTINSXP` | 8 | builtin functions
`R.CHARSXP` | 9 | internal character strings
`R.LGLSXP` | 10 | logical vectors
`R.INTSXP` | 13 | integer vectors
`R.REALSXP` | 14 | numeric vectors
`R.CPLXSXP` | 15 | complex vectors
`R.STRSXP` | 16 | character vectors
`R.DOTSXP` | 17 | dot-dot-dot object
`R.ANYSXP` | 18 | make “any” args work
`R.VECSXP` | 19 | list (generic vector)
`R.EXPRSXP` | 20 | expression vector
`R.BCODESXP` | 21 | byte code
`R.EXTPTRSXP` | 22 | external pointer
`R.WEAKREFSXP` | 23 | weak reference
`R.RAWSXP` | 24 | raw vector
`R.OBJSXP` | 25 | objects not of simple type

If all of this makes sense to you, then enjoy and happy coding. If not, then stick to using the luajr.lua module and don’t worry about it too much – you probably don’t need this anyway!