Tomas Kalibera
2019-Nov-18 08:36 UTC
[Rd] BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"
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. > > > /HenrikA shorter example is > p1 <- .Primitive('+') ; p2 <- p1 ; attr(p1, "myattr") <- 1 ; p2 function (e1, e2)? .Primitive("+") attr(,"myattr") [1] 1 Builtins have referential semantics in R (like e.g. environments, but also some other types). Tomas> > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
Martin Maechler
2019-Nov-18 09:45 UTC
[Rd] BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"
>>>>> 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. Martin
Tomas Kalibera
2019-Nov-18 13:23 UTC
[Rd] BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"
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
Possibly Parallel Threads
- BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"
- BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"
- BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"
- BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"
- Warning when calling formals() for `[`.