|
1 | 1 | --- |
2 | 2 | title: Introduction |
3 | | -description: Call Rust code in R! |
| 3 | +description: Write Rust code and call it in R! |
4 | 4 | weight: 2 |
5 | 5 | --- |
6 | 6 |
|
7 | 7 |
|
8 | | -This is the website for `extendr`, a developer-first utility for building R |
9 | | -packages that call Rust code. Of course, you do not have to be a package |
10 | | -developer to find some use in extendr. In fact, anyone who has a need to call |
11 | | -Rust in R can do so with ease. Consider this basic example: |
12 | | - |
13 | | -``` r |
14 | | -# create a Rust function |
15 | | -rextendr::rust_function( |
16 | | - "fn add(a:f64, b:f64) -> f64 { a + b }", |
17 | | - quiet = TRUE |
18 | | -) |
19 | | - |
20 | | -# call it from R |
21 | | -add(2.5, 4.7) |
22 | | -``` |
23 | | - |
24 | | -``` output |
25 | | -[1] 7.2 |
26 | | -``` |
27 | | - |
28 | | -Moving beyond these simple, one-off cases, however, is where extendr really |
29 | | -shines. Any time you have lots of really complex Rust code that requires |
30 | | -seamless integration with R, notably within a package, extendr is the tool for |
31 | | -you. |
32 | | - |
33 | | -Now largely owing to the fact that we are bridging programming languages, you |
34 | | -will rarely proceed directly to extendr's Rust API. You will instead reach for |
35 | | -the R package `rextendr`, which works sort of like `usethis`, automating many of |
36 | | -the repetitive tasks required to setup or scaffold your project, so you can |
37 | | -focus on the important business of writing code. This is done by calling |
38 | | -`rextendr::use_extendr()`, which should feel familiar to anyone who has worked |
39 | | -with `usethis::use_cpp11()`. |
40 | | - |
41 | | -## Create an R package |
42 | | - |
43 | | -The process of building a Rust-powered R package with extendr boils down to |
44 | | -three simple steps: |
45 | | - |
46 | | -1. Setup R package with `usethis::create_package()`. |
47 | | -2. Add extendr scaffolding with `rextendr::use_extendr()`. |
48 | | -3. Build and document with `devtools::document()`. |
49 | | - |
50 | | -Once you have worked through those steps, you can then load your package with |
51 | | -`devtools::load_all()` and start using your package! Here is an example with |
52 | | -just the defaults: |
53 | | - |
54 | | -``` r |
55 | | -# setup R package |
56 | | -usethis::create_package("helloextendr") |
57 | | - |
58 | | -# add extendr scaffolding |
59 | | -rextendr::use_extendr() |
60 | | - |
61 | | -# build and document package |
62 | | -devtools::document() |
63 | | - |
64 | | -# load package |
65 | | -devtools::load_all() |
66 | | - |
67 | | -# call rust function |
68 | | -hello_world() |
69 | | -``` |
70 | | - |
71 | | - [1] "Hello world!" |
72 | | - |
73 | | -A Rust-powered R package in one fell swoop! Now, if you want to see a complete |
74 | | -example of an actual R package, check out the [heck example](@/example.md). |
75 | | - |
76 | | -## What's next? |
77 | | - |
78 | | -- If you do not already have Rust, R, and rextendr, check out our [Installation guide](@/installation.md). |
79 | | -- Want to learn more about Rust? Check out our [Rust tutorials](@/rust-intro/_index.md). |
80 | | -- Ready to dive in to package development? You will want to consult our |
81 | | - [Development guide](@/development/_index.md). |
82 | | -- Have a Rust-powered package and want to publish it to CRAN? Jump to our |
83 | | - [Publishing recommendations](@/publishing/_index.md). |
84 | | -- Here to join the extendr team and contribute to new features and |
85 | | - maintenance? Have a look at our [Guide for contributors](@/contributing/_index.md). |
| 8 | +This is the website for `extendr`, a developer-first utility for building R |
| 9 | +packages that call Rust code. With extendr, you can write Rust code like this: |
| 10 | + |
| 11 | +<div class="code-with-filename"> |
| 12 | + |
| 13 | +**lib.rs** |
| 14 | + |
| 15 | +``` rust |
| 16 | +use extendr_api::prelude::*; |
| 17 | + |
| 18 | +/// Return string `"Hello world!"` to R. |
| 19 | +/// @param name A name to greet. |
| 20 | +/// @export |
| 21 | +#[extendr] |
| 22 | +fn hello(name: String) -> String { |
| 23 | + format!("Hello {name}!") |
| 24 | +} |
| 25 | + |
| 26 | +// Macro to generate exports. |
| 27 | +extendr_module! { |
| 28 | + mod helloextendr; |
| 29 | + fn hello; |
| 30 | +} |
| 31 | +``` |
| 32 | + |
| 33 | +</div> |
| 34 | + |
| 35 | +and then in R you can call it like this: |
| 36 | + |
| 37 | +``` r |
| 38 | +hello("world") |
| 39 | +``` |
| 40 | + |
| 41 | + [1] "Hello world!" |
| 42 | + |
| 43 | +We call the whole project extendr, of course, but it isn't just one thing. It's |
| 44 | +actually a *suite* of software tools. On the Rust side, extendr consists of |
| 45 | +several crates, but you will typically interact with `extender-api`, a |
| 46 | +developer-facing crate providing a host of data structures, traits, and macros — |
| 47 | +like `#[extendr]` in the above example — that make it easy to write Rust code to |
| 48 | +call in R. On the R side, there is `rextendr`, an R package that works sort of |
| 49 | +like `usethis`, sort of like `devtools`, automating many of the repetitive tasks |
| 50 | +required to setup or scaffold your project, allowing you to focus on the |
| 51 | +important business of writing Rust and R code. |
| 52 | + |
| 53 | +<div class="w-fit mx-auto my-4 md:my-8 flex flex-row items-center gap-2"> |
| 54 | + <a href="https://extendr.github.io/extendr/extendr_api/" class="bc btn-lg-outline h-auto p-2 md:p-4 font-mono md:text-[1.5em]"> |
| 55 | + <span class="iconify mdi--language-rust"></span> |
| 56 | + extendr-api |
| 57 | + </a> |
| 58 | + <p class="text-gray-600 dark:text-gray-300 m-0 md:text-[1.5em]">↔</p> |
| 59 | + <a href="https://extendr.github.io/rextendr/" class="bc btn-lg-outline h-auto p-2 md:p-4 font-mono md:text-[1.5em]"> |
| 60 | + rextendr |
| 61 | + <span class="iconify mdi--language-r"></span> |
| 62 | + </a> |
| 63 | +</div> |
| 64 | + |
| 65 | +So, when you go to setup a repository to develop a Rust-powered R package, you |
| 66 | +will reach for rextendr first. Then, when you start writing Rust code for your R |
| 67 | +package, you will turn to extendr-api. |
| 68 | + |
| 69 | +## Create an R package |
| 70 | + |
| 71 | +The process of building a Rust-powered R package with extendr boils down to |
| 72 | +four simple steps: |
| 73 | + |
| 74 | +1. Setup R package with `usethis::create_package()`. |
| 75 | +2. Add extendr scaffolding with `rextendr::use_extendr()`. |
| 76 | +3. Write Rust code and export it with `extendr-api`. |
| 77 | +4. Build and document with `devtools::document()`. |
| 78 | + |
| 79 | +Once you have worked through those steps, you can then load your package with |
| 80 | +`devtools::load_all()` and start using your package! Here is an example that |
| 81 | +loads the above `lib.rs` into your package at `src/rust/src/lib.rs`, compiles |
| 82 | +it, generates wrappers and documentation, and then calls the `hello()` function |
| 83 | +from R: |
| 84 | + |
| 85 | +``` r |
| 86 | +# setup R package |
| 87 | +usethis::create_package("helloextendr") |
| 88 | + |
| 89 | +# add extendr scaffolding |
| 90 | +rextendr::use_extendr() |
| 91 | + |
| 92 | +# build and document package |
| 93 | +devtools::document() |
| 94 | + |
| 95 | +# load package |
| 96 | +devtools::load_all() |
| 97 | + |
| 98 | +# call rust function |
| 99 | +hello("world") |
| 100 | +``` |
| 101 | + |
| 102 | + [1] "Hello world!" |
| 103 | + |
| 104 | +A Rust-powered R package in one fell swoop! Now, if you want to see a complete |
| 105 | +example of an actual R package, check out the [heck example](@/example.md). |
| 106 | + |
| 107 | +## What's next? |
| 108 | + |
| 109 | +- If you do not already have Rust, R, and rextendr, check out our [Installation guide](@/installation.md). |
| 110 | +- Want to learn more about Rust? Check out our [Rust tutorials](@/rust-intro/_index.md). |
| 111 | +- Ready to dive in to package development? You will want to consult our |
| 112 | + [Development guide](@/development/_index.md). |
| 113 | +- Have a Rust-powered package and want to publish it to CRAN? Jump to our |
| 114 | + [Publishing recommendations](@/publishing/_index.md). |
| 115 | +- Here to join the extendr team and contribute to new features and |
| 116 | + maintenance? Have a look at our [Guide for contributors](@/contributing/_index.md). |
0 commit comments