--- title: "04 - Read-only versus Writable R Objects" output: litedown::html_format: options: toc: true number_sections: true vignette: > %\VignetteIndexEntry{04 - Read-only versus Writable R Objects} %\VignetteEngine{litedown::vignette} %\VignetteEncoding{UTF-8} editor: markdown: wrap: sentence bibliography: ["references.bib"] --- ## Read and write In `cpp4r`, when you declare a variable, it is read-only by default as in cpp11 [@vaughan24]. This is different from `Rcpp`, where variables are read-write by default [@eddelbuettel11]. Following from the package created in the previous vignette, try to compile and run the following code by adding it to a new file `src/04_square_coordinates.h`: ```cpp [[cpp4r::register]] integers square_coordinates_(integers x) { integers out = x; for (int i = 0; i < x.size(); ++i) { out[i] = x[i] * x[i]; } return out; } ``` `devtools::load_all()` and `devtools::install()` will fail with the following error: ```bash error: lvalue required as left operand of assignment out[i] = x[i] * x[i]; ``` This is because the argument `x` is a read-only object, you need to explicitly declare a writable variable: ```cpp [[cpp4r::register]] integers square_coordinates(integers x) { writable::integers out = x; for (int i = 0; i < x.size(); ++i) { out[i] = x[i] * x[i]; } return out; } ``` Alternatively, you can declare the argument as writable: ```cpp [[cpp4r::register]] integers square_coordinates_2(writable::integers x) { for (int i = 0; i < x.size(); ++i) { x[i] = x[i] * x[i]; } return x; } ``` Do not forget to include the new header file in `main.cpp`: Document these functions with roxygen and compare their outputs after loading the updated package: ```r cpp4r::register() devtools::document() devtools::load_all() ``` Compare `square_coordinates(1:3)`, `square_coordinates(c(1, 2, 3))`, and `square_coordinates(c(1L, 2L, 3L))`. Why do the outputs differ? Are `integers` and `doubles` interchangeable as `double` and `int` in C++ for reasonable cases? ## References