[Rd] BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"

Tomas Kalibera tom@@@k@||ber@ @end|ng |rom gm@||@com
Mon Nov 18 14:23:12 CET 2019


On 11/18/19 10:45 AM, Martin Maechler wrote:
>>>>>> Tomas Kalibera
>>>>>>      on Mon, 18 Nov 2019 09:36:14 +0100 writes:
>      > On 11/18/19 9:18 AM, Martin Maechler wrote:
>      >>>>>>> Henrik Bengtsson
>      >>>>>>> on Sun, 17 Nov 2019 14:31:07 -0800 writes:
>      >> > $ R --vanilla R version 3.6.1 (2019-07-05) -- "Action of
>      >> > the Toes" Copyright (C) 2019 The R Foundation for
>      >> > Statistical Computing Platform: x86_64-pc-linux-gnu
>      >> > (64-bit) ...
>      >>
>      >> >> str(base::`+`)
>      >> > function (e1, e2)
>      >>
>      >> >> plus <- structure(base::`+`, class = "plus") str(plus)
>      >> > function (e1, e2) - attr(*, "class")= chr "plus"
>      >>
>      >> > ## Hmm ...
>      >> >> str(base::`+`)
>      >> > function (e1, e2) - attr(*, "class")= chr "plus"
>      >>
>      >> >> class(base::`+`) <- NULL str(base::`+`)
>      >> > function (e1, e2)
>      >>
>      >> > ## Hmm ...
>      >> >> str(plus)
>      >> > function (e1, e2)
>      >>
>      >> > Even without assigning to `plus`, you get this behavior:
>      >>
>      >> > $ R --vanilla
>      >> >> structure(base::`+`, class = "plus")
>      >> > function (e1, e2) .Primitive("+") attr(,"class") [1]
>      >> > "plus"
>      >>
>      >> > # Hmm...
>      >> >> str(base::`+`)
>      >> > function (e1, e2) - attr(*, "class")= chr "plus"
>      >>
>      >> > Looks to be the case for common (all?) .Primitive
>      >> > functions.
>      >>
>      >> No need for 'base::' (who would be crazy enough to redefine `+`?)
>      >> nor str() actually:
>      >>
>      >> attr(`+`, "class") <- NULL  # (reset)
>      >> `+`
>      >> structure(`+`, class = "plus")
>      >> `+`
>      >>
>      >> is clearly convincing and minimal
>      >>
>      >>> attr(`+`, "class") <- NULL
>      >>> `+`
>      >> function (e1, e2)  .Primitive("+")
>      >>> structure(`+`, class = "plus")
>      >> function (e1, e2)  .Primitive("+")
>      >> attr(,"class")
>      >> [1] "plus"
>      >>> `+`
>      >> function (e1, e2)  .Primitive("+")
>      >> attr(,"class")
>      >> [1] "plus"
>      >> ---------------------------------------------------------
>      >>
>      >> > Is this expected?
>      >>
>      >> no.  (at least not by 99.999% of R users)
>      >>
>      >>
>      >> > Should I report this one to Bugzilla?
>      >> yes, please.
>      >>
>      >> > /Henrik
>
>      > A shorter example is
>
>      >> p1 <- .Primitive('+') ; p2 <- p1 ; attr(p1, "myattr") <- 1 ; p2
>
>      > function (e1, e2)  .Primitive("+")
>      > attr(,"myattr")
>      > [1] 1
>
> beautiful ; thank you, Tomas !
>
>      > Builtins have referential semantics in R (like e.g. environments, but
>      > also some other types).
>
>      > Tomas
>
>   [aarh.. I knew it ... but am showing my age:  I had forgotten about it.]
>
> I forget (and don't have time just now to find out) where we
> have documented it;  it may be good to document also in official
> user exposed places such say the  ?.Primitive  help page.

I think internal objects such as builtins should never be modified by 
user code in the first place. We had to add detection for modifications 
of NIL and symbols in the past, maybe we will have to do it for builtins 
as well.

Environments can be used in user code as objects with referential 
semantics, e.g. to keep mutable state.

Tomas
>
> Martin



More information about the R-devel mailing list