---
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
