В Thu, 24 Apr 2025 12:36:57 +0000
Tony Wilkes <tony_a_wil...@outlook.com> пишет:

> One use-case for this is to check if it's save to modify an object by
> reference.

I think you might need NOT_SHARED() for that, except it's far from
being simple, especially once you pass arbitrary expressions (not just
variable names) as arguments to your function:
https://developer.r-project.org/Refcnt.html

> For example, when saying x <- base::letters, x is not save
> to modify by reference: Although the binding of x itself is not
> locked, the binding of base::letters is locked, and we obviously
> don't want to modify base::letters.

The situation is more dangerous than that. When 'x' references the same
object as base::letters (which is a locked binding), you can still
modify this object from C code, given its SEXP address, and see the
changes from either binding; R won't be able to stop you. (That's the
danger of by-reference operations like those implemented in data.table.)

On the other hand, if you assign a new value to the 'x' binding inside
a given environment, base::letters and any other objects referencing it
will retain their original values; there is no need to worry about
other bindings being locked.

> R has a few pass-by-reference classes (like environments)

These are different. You can lock a _binding_ to an environment and
still change the _value_ of that environment precisely because it's a
mutable, pass-by-reference object:

x <- new.env()
y <- x
lockBinding('x', environment())
# x$foo <- 'bar' # would signal an error, but:
assign('foo', 'bar', envir = x) # works
x$foo # [1] "bar"
identical(x, y) # [1] TRUE

R switched to reference counting by default in version 4.0. One
downside of the reference counts as currently implemented is that when
an object containing references to other objects is garbage-collected,
the reference counts of the child objects are not decremented:

x <- 1
invisible(replicate(999, list(x)))
gc(full = TRUE)
.Internal(inspect(x))
# @5618cd515488 14 REALSXP g1c1 [MARK,REF(2000)] (len=1, tl=0) 1

'x' retains a reference count of 2000 despite the 999 lists that
previously referenced it no longer exist. This is possible to change,
but at the cost of slowing down the garbage collector.

-- 
Best regards,
Ivan

______________________________________________
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel

Reply via email to