extendr / extendr.github.io

https://extendr.github.io/
MIT License
5 stars 3 forks source link

Breaking the **R**ules: mutable references #22

Open JosiahParry opened 7 months ago

JosiahParry commented 7 months ago

This could be an advanced section with hazards all over it that discusses how to mutate R objects in place.

This is against the clone on write (Cow) rules of R. BUT if you created and own all of the objects, it may make sense to mutably handle them. in some cases.

JosiahParry commented 7 months ago

For example this will let you modify the first element of an integer vector in place

#[extendr]
fn changeme(x: Integers) {
    let mut x = x;
    x[0] = 100.into();
}
JosiahParry commented 7 months ago
#[extendr]
fn swap_list_element(x: List, y: Robj, idx: i32) {
    let mut x = x;
    let _ = x.set_elt(idx as usize, y);
}
(o <- list(x = 1, y = 2, z = "a"))
#> $x
#> [1] 1
#> 
#> $y
#> [1] 2
#> 
#> $z
#> [1] "a"

# get address
addr_1 <- tracemem(o)

# swap in place 
swap_list_element(o, letters, 0)

# print 
o
#> $x
#>  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
#> [20] "t" "u" "v" "w" "x" "y" "z"
#> 
#> $y
#> [1] 2
#> 
#> $z
#> [1] "a"

# get address again
addr_2 <- tracemem(o)

# check that the addresses are the same 
identical(addr_1, addr_2)
#> [1] TRUE

Created on 2024-03-02 with reprex v2.0.2

JosiahParry commented 7 months ago

This could be a cool place to recreate rlang::vec_poke_n() using Rust