Skip to content
Prev 63334 / 63424 Next

Assign in place and reference counting

You are re-inventing the reference classes (or R6 if you prefer package space). By definition, environments are the only mutable objects in R, no other objects are, so what you are doing is adding a reference wrapper around an immutable object.

The fact that `items` can be modified in place is orthogonal to that: as Ivan said, that's just an under-the-hood optimization. The language definition says that the `items` before and after the subassignment are two different objects - both immutable. From user's perspective there is no difference, but R is smart enough to optimize away the copy if it is safe, i.e., when it knows for sure that no one can access the original object so it can cheat and re-use the original object instead, but that fact is intended to be entirely invisible to the user.

Clearly, for the example above the entire discussion is irrelevant, since copies are much cheaper than function calls so unless you have a stack of billions it makes no difference. In addition, your get() will always return a copy regardless, because you are forcing it by the subsetting, so, paradoxically, the na?ve (yet more readable) implementation

        items = character()
        add = function(x) items <<- c(items, x)
        get = function() items

is actually faster if you have comparable number of gets and adds since gets don't need to copy (and uses less memory). My recommendation would be to not worry about internal optimisations because a) they change all the time so your assumptions about undefined behavior may be broken and backfire, b) the time you spend on it is many orders of magnitude more than any potential savings and c) trying to exploit specific behavior makes code less readable and thus more error-prone.

Cheers,
?imon