Module OCamlR

Bindings for the R interpreter.

It encapsulates the functionalities of the libR.so shared library provided by the R software. This enables us to embed the R interpreter into Objective Caml, to execute R code from Objective Caml and to exchange data structures between R and Objective Caml. A lot of information on R internals can be found in the official documentation as well as in this document.

THREAD SAFETY

It is important to understand that this binding is a rather low-level binding of R functionality. As such, it is no more thread-safe than R itself, which is not thread-safe at all. Therefore, avoid real threading unless you know what you're doing...

DATA CONVERSION

R is an array-oriented language. Therefore, simple values such as a boolean, a string, a number, are in fact encapsulated, in R, in an array of booleans, an array of strings, an array of numbers. For a simple value, the array has only one element.

Moreover, as R is scientific software, it is important that data types be correctly matched between Objective Caml and R. At the moment, they are not. I am thinking here of the 31/32 bit issues, or 63/64 bit issue, or, for instance.

Internal representation of R values.

type sexp

Low-level SEXP typing.

type 'a sxp = private sexp
type nilsxp = [ `Nil ] sxp
type symsxp = [ `Sym ] sxp
type langsxp = [ `Lang ] sxp
type listsxp = [ `List ] sxp
type dotsxp = [ `Dot ] sxp
type closxp = [ `Clo ] sxp
type envsxp = [ `Env ] sxp
type promsxp = [ `Prom ] sxp
type specialsxp = [ `Special ] sxp
type builtinsxp = [ `Builtin ] sxp
type vecsxp = [ `Vec ] sxp
type charsxp = [ `Char ] sxp
type lglsxp = [ `Lgl ] sxp
type intsxp = [ `Int ] sxp
type realsxp = [ `Real ] sxp
type strsxp = [ `Str ] sxp
type rawsxp = [ `Raw ] sxp
type exprsxp = [ `Expr ] sxp
type 'a nonempty_list = [< `List | `Lang | `Dots ] as 'a

R-ints: Language objects (LANGSXP) are calls (including formulae and so on). Internally they are pairlists with first element a reference to the function to be called with remaining elements the actual arguments for the call. Although this is not enforced, many places in the code assume that the pairlist is of length one or more, often without checking.

type internallist = [
| `Nil
| `List
| `Lang
| `Dots
]

Type of low-level internal list. In R, such * internal lists may be empty, a pairlist or * a call which is somewhat similar to closure * ready for execution.

type 'a pairlist = [< `Nil | `List ] as 'a
type vector = [
| `Char
| `Lgl
| `Int
| `Real
| `Str
| `Raw
| `Expr
| `Vec
]
module type SXP = sig ... end
module Sexp : SXP with type t = sexp
module Nilsxp : sig ... end
module Dotsxp : sig ... end
module Envsxp : sig ... end
module Langsxp : sig ... end
module Symsxp : sig ... end

Vector types

R is an array-oriented language. Therefore, simple values such as a boolean, a string, a number, are in fact encapsulated, in R, in an array of booleans, an array of strings, an array of numbers. For a simple value, the array has only one element.

module type Vector = sig ... end
module type Atomic_vector = sig ... end
module Intsxp : Atomic_vector with type t = intsxp and type repr = int

R array of integer values

module Lglsxp : Atomic_vector with type t = lglsxp and type repr = bool

R array of boolean values

module Realsxp : Atomic_vector with type t = realsxp and type repr = float

R array of float values

module Strsxp : Atomic_vector with type t = strsxp and type repr = string

R array of string values

module Vecsxp : Vector with type t = vecsxp and type repr = Sexp.t

R list

Value inspection

module Sexptype : sig ... end

Algebraic datatype reflecting R's dynamic typing.

module Pretty : sig ... end

Provides facilities to inspect internal structure of SEXPs. Useful in the toplevel when you encounter unexpected R values.

Parsing R code.

type parse_status =
| Parse_Null
| Parse_OK
| Parse_Incomplete
| Parse_Error
| Parse_EOF

Outcome of a parsing request.

exception Parsing_failure of parse_status * string

Exception raised when parsing fails.

val parse_string : ?⁠max:int -> string -> langsxp list

Parse a string of R code into R calls.

parameter max

If omitted, parse the whole R code, even if there are multiple statements. Otherwise, maximum number of statements to parse.

raises Parsing_failure

When parsing fails.

val parse : string -> langsxp

Parse the first R statement in the given R code.

Evaluation of R code and calls.

exception Runtime_error of langsxp * string
module type Conversion = sig ... end
module Enc : Conversion with type 'a t = 'a -> Sexp.t
module Dec : Conversion with type 'a t = Sexp.t -> 'a
val symbol : ?⁠generic:bool -> string -> Sexp.t

Retrieves an R symbol from the symbol table, given its name.

val eval_string : string -> Sexp.t

string takes a string containing R code, and feeds it to the R interpreter. You get the resulting value back. The typing of this function is deliberately unsafe in order to allow the user to type it precisely.

Bug: currently, if you try to execute a statement that refers to symbols that haven't been loaded, you get a segfault. For instance, evaluating a string containing the rbinom symbol without the R.stats package being loaded raises a segfault.

type arg

Convenience functions to wrap up arguments, when mapping R functions to Objective Caml functions.

val arg : 'a Enc.t -> ?⁠name:string -> 'a -> arg
val opt_arg : 'a Enc.t -> string -> 'a option -> arg
val call : Sexp.t -> arg list -> Sexp.t

call f args evaluates an the R function f with respect to a list of arguments. Argument None is ignored, and Some (name, sexp) is the argument whose optional name is name and whose value is sexp. The typing of this function is deliberately unsafe in order to allow the user to type it precisely.

Initialisation

We provide two mechanisms to activate an R interpreter from OCaml-R:

The first mechanism consists of low-level bindings to the initialisation and termination functions of the libR.so shared library. While this is a rather flexible approach, it has the downside of not being a very static approach, specifically if your intention if to write Objective Caml bindings for a dependent bunch of R packages.

The second mechanism is a static, functorial approach: You just have to create a module with the Interpreter functor to initialise the R interpreter. You provide initialisation details through a module of module type Environment, and Interpreter will set it up correctly.

This functorial facility is available from the OCaml_R module: This OCaml_R module has the sole purpose of initialising the R interpreter with the Standard Environment module. No need to worry about initialisation details.

To create bindings for a dependent bunch of R packages, you simply have to make them depend on the findlib R.interpreter package, which involves the OCaml_R module. This is also convenient on the toplevel, where you simply have to have to invoke the #require "R.interpreter" directive to set up the interpreter.

exception Initialisation_failed

Denotes failure to initialise the R interpreter.

val init : ?⁠name:string -> ?⁠argv:string list -> ?⁠env:(string * string) list -> ?⁠packages:string list option -> ?⁠sigs:bool -> unit -> unit

init initialises the embedded R interpreter.

parameter name

Name of program. Defaults to Sys.argv.(0).

parameter argv

Command line options given to libR.so. Defaults to rest of Sys.argv.

parameter env

Environment variables to be set for R. Defaults to reasonable values.

parameter packages

Packages to be loaded at startup. If None, load the usual standard library.

parameter sigs

If false, stops R from setting his signal handlers. Defaults to false.

raises Initialisation_failed

In case R could not be started.

val terminate : unit -> unit

Terminates the R session.

module type Environment = sig ... end
module Standard_environment : Environment

The Standard module contains initialisation details for libR.so. These informations are determined when the binding is being compiled.

module Interpreter_initialization : functor (Env : Environment) -> sig ... end

Functor used to initialise statically an R interpreter, given initialisation details provided by the provided Env module.

module Low_level : sig ... end
val attributes : sexp -> (Symsxp.description * sexp) list
val pairlist_of_list : (sexp * sexp) list -> [> internallist ] sxp