Skip to content

Commit d437e7b

Browse files
committed
strings chapter again, again
1 parent 9acd81b commit d437e7b

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"hash": "4876597e0d5a972f10de82702b5692bc",
3+
"result": {
4+
"engine": "knitr",
5+
"markdown": "---\ntitle: \"Character Strings\"\n---\n\n::: {.cell}\n\n:::\n\n\nThe R runtime performs [string interning](https://en.wikipedia.org/wiki/String_interning) to\nall of its string elements. This means, that whenever R encounters a new string,\nit adds it to its internal string intern pool. Therefore, it is unsound to\naccess R strings mutably.\n\n::: {.callout-tip }\nA string intern pool can be thought of as a container that stores all distinct\nstrings, and then provides a lightweight reference counted variable back to it.\nAn example of such a string interner is the [`lasso`](https://crates.io/crates/lasso) crate.\n:::\n\nLet's look at a concrete example:\n\n\n::: {.cell}\n\n```{.rust .cell-code}\n#[extendr]\nfn hello_world() -> &'static str {\n \"Hello world!\"\n}\n```\n:::\n\n::: {.cell}\n\n```{.r .cell-code}\n.Internal(inspect(hello_world()))\n#> @11c4bd628 16 STRSXP g0c1 [] (len=1, tl=0)\n#> @119641448 09 CHARSXP g0c2 [REF(2),gp=0x60,ATT] [ASCII] [cached] \"Hello world!\"\n```\n:::\n\n\nThen, any time R encounters `\"Hello world!\"`, it retrieves it from the pool, rather\nthan re-instantiate it\n\n\n::: {.cell}\n\n```{.r .cell-code}\n.Internal(inspect(\"Hello world!\"))\n#> @11b2f0780 16 STRSXP g0c1 [REF(2)] (len=1, tl=0)\n#> @119641448 09 CHARSXP g0c2 [MARK,REF(3),gp=0x60,ATT] [ASCII] [cached] \"Hello world!\"\n```\n:::\n\n\nThe `STRSXP` is different, due to R's clone semantics, but the underlying\nstring `CHARSXP` is the same. Thus, equality is determined if two strings\nhave the same pointer, rather than if they have the same bytes.\n\nTherefore, `extendr` does not provide mutable access to an R string, because it breaks\nthe assumption that all strings are the immutable.",
6+
"supporting": [],
7+
"filters": [
8+
"rmarkdown/pagebreak.lua"
9+
],
10+
"includes": {},
11+
"engineDependencies": {},
12+
"preserve": {},
13+
"postProcess": true
14+
}
15+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,46 @@
11
---
22
title: "Character Strings"
33
---
4+
5+
```{r}
6+
#| echo: false
7+
library(rextendr)
8+
```
9+
10+
The R runtime performs [string interning](https://en.wikipedia.org/wiki/String_interning) to
11+
all of its string elements. This means, that whenever R encounters a new string,
12+
it adds it to its internal string intern pool. Therefore, it is unsound to
13+
access R strings mutably.
14+
15+
::: {.callout-tip }
16+
A string intern pool can be thought of as a container that stores all distinct
17+
strings, and then provides a lightweight reference counted variable back to it.
18+
An example of such a string interner is the [`lasso`](https://crates.io/crates/lasso) crate.
19+
:::
20+
21+
Let's look at a concrete example:
22+
23+
```{extendrsrc}
24+
#[extendr]
25+
fn hello_world() -> &'static str {
26+
"Hello world!"
27+
}
28+
```
29+
30+
```{r}
31+
.Internal(inspect(hello_world()))
32+
```
33+
34+
Then, any time R encounters `"Hello world!"`, it retrieves it from the pool, rather
35+
than re-instantiate it
36+
37+
```{r}
38+
.Internal(inspect("Hello world!"))
39+
```
40+
41+
The `STRSXP` is different, due to R's clone semantics, but the underlying
42+
string `CHARSXP` is the same. Thus, equality is determined if two strings
43+
have the same pointer, rather than if they have the same bytes.
44+
45+
Therefore, `extendr` does not provide mutable access to an R string, because it breaks
46+
the assumption that all strings are the immutable.

0 commit comments

Comments
 (0)