<div dir="ltr"><div>Thanks a lot!</div><div><br></div>I thought that was a bug of data.table, when I tried to learn data.table. Obviously, I was wrong. It's a feature of data.table, in which all set functions change their input by reference. It also provide function copy when a copy is needed.<div><br></div><div>Based on suggestion from Romain, I may just stay on the safe side and do not modify argument passed to C++ from R. The users of data.table should be aware of that data.table object is passed by reference, and call function copy when needed. For other R objects, it seems cause too much trouble. It's hard to detect variables pointing to the same place and I don't want to provide a copy function.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 22, 2014 at 11:40 AM, Gabor Grothendieck <span dir="ltr"><<a href="mailto:ggrothendieck@gmail.com" target="_blank">ggrothendieck@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Tue, Oct 21, 2014 at 9:22 PM, Chenliang Xu <<a href="mailto:luckyrand@gmail.com">luckyrand@gmail.com</a>> wrote:<br>
> Hello,<br>
><br>
> With the following inplace sorting example, I understand the value of `a` is<br>
> sorted inplace, but it's strange to see the value of `b` is also modified.<br>
> This can cause some hard to detect bug, since the cpp function may modify a<br>
> variable defined in other scope.<br>
><br>
> It seems that rcpp doesn't respect the named field, which is adopted by R to<br>
> implement copy-on-modify. I don's see an easy fix on C++ side, since the<br>
> called cpp function has no information about variable binding in R. A<br>
> possible fix is adding a function `inplace` to R, which ensure the returned<br>
> variable has named filed = 0 so is safe to modify inplace. Then, we have to<br>
> call the function as `stl_sort_inplace(inplace(a))`, which seems odd but is<br>
> also informative. It shows clearly that we are breaking the pass-by-value<br>
> rule in R.<br>
><br>
> ```cpp<br>
> #include <Rcpp.h><br>
> using namespace Rcpp;<br>
><br>
> // [[Rcpp::export]]<br>
> void stl_sort_inplace(NumericVector x) {<br>
>     std::sort(x.begin(), x.end());<br>
> }<br>
><br>
> ```<br>
><br>
> ```r<br>
> a <- seq(1, 0.1, -0.1)<br>
> b <- a<br>
> #  [1] 1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1<br>
><br>
> stl_sort_inplace(a)<br>
><br>
> a<br>
> #  [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0<br>
><br>
> b<br>
> #  [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0<br>
><br>
> a <- seq(1, 0.1, -0.1)<br>
> pure_function <- function (x) {<br>
>   y <- x<br>
>   stl_sort_inplace(y)<br>
>   print(y)<br>
> }<br>
> pure_function(a)<br>
> a<br>
> #  [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0<br>
><br>
<br>
</div></div>This is common among C++ software called by R that modifies R objects<br>
in place. For example, below DT2 is modified:<br>
<br>
> library(data.table)<br>
...junk...<br>
> DT <- data.table(a = 1:3)<br>
> DT2 <- DT<br>
> DT[, b:=a]<br>
> DT2<br>
   a b<br>
1: 1 1<br>
2: 2 2<br>
3: 3 3<br>
</blockquote></div><br></div>