extendr - A safe and user-friendly R extension interface using Rust

rextendr logo

Github Actions Build Status Crates.io Documentation License: MIT

The extendr suite of software packages provides a Rust extension mechanism for R, thus bringing the computing power of Rust to the statistical programming environment of R. The following code provides a simple illustration of how extendr achieves this.

use extendr_api::prelude::*;

#[derive(Debug)]
struct Person {
    pub name: String,
}

#[extendr]
impl Person {
    fn new() -> Self {
        Self { name: "".to_string() }
    }

    fn set_name(&mut self, name: &str) {
        self.name = name.to_string();
    }

    fn name(&self) -> &str {
        self.name.as_str()
    }
}

#[extendr]
fn my_function() { }

// Macro to generate exports
extendr_module! {
    mod classes;
    impl Person;
    fn my_function;
}

The #[extendr] attribute causes the compiler to generate wrapper and registration functions for R which are called when the package is loaded, thus allowing one to access Rust functions and structures in an R session:

# call function
my_function()

# create Person object
p <- Person$new()
p$set_name("foo")
p$name()   # "foo" is returned

This, of course, is just the tip of the iceberg, for there are many ways to use extendr in R:

Software Overview

The software packages that make up extendr include:

  • Rust crates:
    • extendr-api - provides the ergonomic, opinionated, and safe interface to R in Rust
    • extendr-macros - crate responsible generation of wrappers, derive macros for conversion to R, etc.
    • extendr-engine - crate that enables launching R sessions from Rust code;
  • An R package rextendr that helps scaffolding extendr-enabled packages or compiling Rust code interactively; and
  • libR-sys - provides auto-generated bindings to R’s C-facilities (or C-API) in Rust