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
Benjamin Tyner
2019-Nov-26 03:34 UTC
[Rd] BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"
For what it's worth, the current behavior seems to have begun starting with version 3.6.0. If I run in version 3.5.3: > p1 <- .Primitive('+') ; p2 <- p1 ; attr(p1, "myattr") <- 1 ; p2 function (e1, e2)? .Primitive("+")> 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 /
Martin Maechler
2019-Nov-26 08:00 UTC
[Rd] BUG?: A copy of base::`+` (primitive) is not a clone but a "pointer"
>>>>> Benjamin Tyner >>>>> on Mon, 25 Nov 2019 22:34:33 -0500 writes:> For what it's worth, the current behavior seems to have begun starting > with version 3.6.0. If I run in version 3.5.3: >> p1 <- .Primitive('+') ; p2 <- p1 ; attr(p1, "myattr") <- 1 ; p2 > function (e1, e2)? .Primitive("+") No. What changed was just the *printing* ! (still in R 3.5.x) :> p1 <- .Primitive('+') ; p2 <- p1 ; attr(p1, "myattr") <- pi ; attributes(p2)$myattr [1] 3.141593>
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 `[`.