`@<-` modify its argument when slot is externalptr

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

`@<-` modify its argument when slot is externalptr

Jialin Ma
Dear all,

I am confused about the inconsistent behaviors of `@<-` operator when
used in different ways. Consider the following example:

  library(inline)
 
  # Function to generate an externalptr object with random address
  new_extptr <- cfunction(c(), '
    SEXP val = PROTECT(ScalarLogical(1));
    SEXP out = PROTECT(R_MakeExternalPtr(&val, R_NilValue, val));
    UNPROTECT(2);
    return(out);
  ')

  setClass("S4ClassHoldingExtptr", contains = "externalptr")

  subs_extptr_1 <- function(x) {
    x@.xData <- new_extptr()
    x
  }

  subs_extptr_2 <- function(x) {
    x <- `@<-`(x, ".xData", new_extptr())
    x
  }

I expect functions "subs_extptr_1" and "subs_extptr_2" should be
semantically identical. (is it right?)

But it seems that "subs_extptr_2" will modify its argument while
"subs_extptr_1" won't.

  x <- new("S4ClassHoldingExtptr", new_extptr())
  y <- x
  y
   # An object of class "S4ClassHoldingExtptr"
   # <pointer: 0x7ffc60971eb0>
 
  subs_extptr_1(x)
   # An object of class "S4ClassHoldingExtptr"
   # <pointer: 0x7ffc60974250>
  x
   # An object of class "S4ClassHoldingExtptr"
   # <pointer: 0x7ffc60971eb0>
  y
   # An object of class "S4ClassHoldingExtptr"
   # <pointer: 0x7ffc60971eb0>

As shown above, "subs_extptr_1" will not modify x or y.

  subs_extptr_2(x)
   # An object of class "S4ClassHoldingExtptr"
   # <pointer: 0x7ffc60973f30>
  x
   # An object of class "S4ClassHoldingExtptr"
   # <pointer: 0x7ffc60973f30>
  y
   # An object of class "S4ClassHoldingExtptr"
   # <pointer: 0x7ffc60973f30>

However, "subs_extptr_2" will modify both x and y.

Is this behavior expected?

Thanks,
Jialin


> sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: x86_64-suse-linux-gnu (64-bit)
Running under: openSUSE Tumbleweed

Matrix products: default
BLAS: /usr/lib64/R/lib/libRblas.so
LAPACK: /usr/lib64/R/lib/libRlapack.so

locale:
 [1] LC_CTYPE=en_US.UTF-
8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8      
 [4] LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-
8    LC_MESSAGES=en_US.UTF-8  
 [7] LC_PAPER=en_US.UTF-
8       LC_NAME=C                  LC_ADDRESS=C              
[10] LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8
LC_IDENTIFICATION=C      

attached base packages:
[1] stats     graphics  grDevices
utils     datasets  methods   base    

other attached packages:
[1] inline_0.3.14 magrittr_1.5

loaded via a namespace (and not attached):
[1] compiler_3.4.1 tools_3.4.1    yaml_2.1.18    ulimit_0.0-3

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: `@<-` modify its argument when slot is externalptr

luke-tierney
On Sun, 18 Mar 2018, Jialin Ma wrote:

> Dear all,
>
> I am confused about the inconsistent behaviors of `@<-` operator when
> used in different ways. Consider the following example:
>
>  library(inline)
>
>  # Function to generate an externalptr object with random address
>  new_extptr <- cfunction(c(), '
>    SEXP val = PROTECT(ScalarLogical(1));
>    SEXP out = PROTECT(R_MakeExternalPtr(&val, R_NilValue, val));
>    UNPROTECT(2);
>    return(out);
>  ')
>
>  setClass("S4ClassHoldingExtptr", contains = "externalptr")
>
>  subs_extptr_1 <- function(x) {
>    x@.xData <- new_extptr()
>    x
>  }
>
>  subs_extptr_2 <- function(x) {
>    x <- `@<-`(x, ".xData", new_extptr())
>    x
>  }
>
> I expect functions "subs_extptr_1" and "subs_extptr_2" should be
> semantically identical. (is it right?)

No. The are similar but not identical. It is not a good idea to call
replacement functions directly and should be avoided. Doing so may need
to become a runtime error or at least a warning in the future.

Nevertheless, this is a bug in the implementation @<-.A simpler example is

x <- setClass("foo", slots = "bar")
x <- new("foo", bar = 1)
y <- x
y@bar
##  [1] 1
`@<-`(x, bar, 2)
y@bar
##  [1] 2

Will be fixed soon in R-devel.

Best,

luke

> x <- setClass("foo", slots = "bar")
> x <- new("foo", bar = 1)
> y <- x
> `@<-`(x, bar, 2)
An object of class "foo"
Slot "bar":
[1] 2

> x
An object of class "foo"
Slot "bar":
[1] 2

> x$bar
Error in x$bar : $ operator not defined for this S4 class
> x@bar
[1] 2

> But it seems that "subs_extptr_2" will modify its argument while
> "subs_extptr_1" won't.
>
>  x <- new("S4ClassHoldingExtptr", new_extptr())
>  y <- x
>  y
>   # An object of class "S4ClassHoldingExtptr"
>   # <pointer: 0x7ffc60971eb0>
>
>  subs_extptr_1(x)
>   # An object of class "S4ClassHoldingExtptr"
>   # <pointer: 0x7ffc60974250>
>  x
>   # An object of class "S4ClassHoldingExtptr"
>   # <pointer: 0x7ffc60971eb0>
>  y
>   # An object of class "S4ClassHoldingExtptr"
>   # <pointer: 0x7ffc60971eb0>
>
> As shown above, "subs_extptr_1" will not modify x or y.
>
>  subs_extptr_2(x)
>   # An object of class "S4ClassHoldingExtptr"
>   # <pointer: 0x7ffc60973f30>
>  x
>   # An object of class "S4ClassHoldingExtptr"
>   # <pointer: 0x7ffc60973f30>
>  y
>   # An object of class "S4ClassHoldingExtptr"
>   # <pointer: 0x7ffc60973f30>
>
> However, "subs_extptr_2" will modify both x and y.
>
> Is this behavior expected?
>
> Thanks,
> Jialin
>
>
>> sessionInfo()
> R version 3.4.1 (2017-06-30)
> Platform: x86_64-suse-linux-gnu (64-bit)
> Running under: openSUSE Tumbleweed
>
> Matrix products: default
> BLAS: /usr/lib64/R/lib/libRblas.so
> LAPACK: /usr/lib64/R/lib/libRlapack.so
>
> locale:
> [1] LC_CTYPE=en_US.UTF-
> 8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8
> [4] LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-
> 8    LC_MESSAGES=en_US.UTF-8
> [7] LC_PAPER=en_US.UTF-
> 8       LC_NAME=C                  LC_ADDRESS=C
> [10] LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8
> LC_IDENTIFICATION=C
>
> attached base packages:
> [1] stats     graphics  grDevices
> utils     datasets  methods   base
>
> other attached packages:
> [1] inline_0.3.14 magrittr_1.5
>
> loaded via a namespace (and not attached):
> [1] compiler_3.4.1 tools_3.4.1    yaml_2.1.18    ulimit_0.0-3
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

--
Luke Tierney
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:   [hidden email]
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: `@<-` modify its argument when slot is externalptr

Lukas Stadler

> On 18.03.2018, at 15:54, [hidden email] wrote:
>
> x <- setClass("foo", slots = "bar")
> x <- new("foo", bar = 1)
> y <- x
> y@bar
> ##  [1] 1
> `@<-`(x, bar, 2)
> y@bar
> ##  [1] 2
>
> Will be fixed soon in R-devel.
>

I always assumed that this behavior is intentional, in order to make S4 "initialize" work efficiently.

- Lukas
        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: `@<-` modify its argument when slot is externalptr

Jialin Ma
In reply to this post by luke-tierney
Hi Luke,

Thanks a lot for the explanation. I also noted that `@<-` will not
modify the argument when the slot is ".Data". For example

setClass("foo", contains = "numeric")
x <- new("foo", 2)
y <- x
y
# An object of class "foo"
# [1] 2

`@<-`(x, .Data, 42)
# An object of class "foo"
# [1] 42
x
# An object of class "foo"
# [1] 2
y
# An object of class "foo"
# [1] 2

Best regards,
Jialin


On Sun, 2018-03-18 at 09:54 -0500, [hidden email] wrote:

> On Sun, 18 Mar 2018, Jialin Ma wrote:
>
> > Dear all,
> >
> > I am confused about the inconsistent behaviors of `@<-` operator
> > when
> > used in different ways. Consider the following example:
> >
> >  library(inline)
> >
> >  # Function to generate an externalptr object with random address
> >  new_extptr <- cfunction(c(), '
> >    SEXP val = PROTECT(ScalarLogical(1));
> >    SEXP out = PROTECT(R_MakeExternalPtr(&val, R_NilValue, val));
> >    UNPROTECT(2);
> >    return(out);
> >  ')
> >
> >  setClass("S4ClassHoldingExtptr", contains = "externalptr")
> >
> >  subs_extptr_1 <- function(x) {
> >    x@.xData <- new_extptr()
> >    x
> >  }
> >
> >  subs_extptr_2 <- function(x) {
> >    x <- `@<-`(x, ".xData", new_extptr())
> >    x
> >  }
> >
> > I expect functions "subs_extptr_1" and "subs_extptr_2" should be
> > semantically identical. (is it right?)
>
> No. The are similar but not identical. It is not a good idea to call
> replacement functions directly and should be avoided. Doing so may
> need
> to become a runtime error or at least a warning in the future.
>
> Nevertheless, this is a bug in the implementation @<-.A simpler
> example is
>
> x <- setClass("foo", slots = "bar")
> x <- new("foo", bar = 1)
> y <- x
> y@bar
> ##  [1] 1
> `@<-`(x, bar, 2)
> y@bar
> ##  [1] 2
>
> Will be fixed soon in R-devel.
>
> Best,
>
> luke
>
> > x <- setClass("foo", slots = "bar")
> > x <- new("foo", bar = 1)
> > y <- x
> > `@<-`(x, bar, 2)
>
> An object of class "foo"
> Slot "bar":
> [1] 2
>
> > x
>
> An object of class "foo"
> Slot "bar":
> [1] 2
>
> > x$bar
>
> Error in x$bar : $ operator not defined for this S4 class
> > x@bar
>
> [1] 2
>
> > But it seems that "subs_extptr_2" will modify its argument while
> > "subs_extptr_1" won't.
> >
> >  x <- new("S4ClassHoldingExtptr", new_extptr())
> >  y <- x
> >  y
> >   # An object of class "S4ClassHoldingExtptr"
> >   # <pointer: 0x7ffc60971eb0>
> >
> >  subs_extptr_1(x)
> >   # An object of class "S4ClassHoldingExtptr"
> >   # <pointer: 0x7ffc60974250>
> >  x
> >   # An object of class "S4ClassHoldingExtptr"
> >   # <pointer: 0x7ffc60971eb0>
> >  y
> >   # An object of class "S4ClassHoldingExtptr"
> >   # <pointer: 0x7ffc60971eb0>
> >
> > As shown above, "subs_extptr_1" will not modify x or y.
> >
> >  subs_extptr_2(x)
> >   # An object of class "S4ClassHoldingExtptr"
> >   # <pointer: 0x7ffc60973f30>
> >  x
> >   # An object of class "S4ClassHoldingExtptr"
> >   # <pointer: 0x7ffc60973f30>
> >  y
> >   # An object of class "S4ClassHoldingExtptr"
> >   # <pointer: 0x7ffc60973f30>
> >
> > However, "subs_extptr_2" will modify both x and y.
> >
> > Is this behavior expected?
> >
> > Thanks,
> > Jialin
> >
> >
> > > sessionInfo()
> >
> > R version 3.4.1 (2017-06-30)
> > Platform: x86_64-suse-linux-gnu (64-bit)
> > Running under: openSUSE Tumbleweed
> >
> > Matrix products: default
> > BLAS: /usr/lib64/R/lib/libRblas.so
> > LAPACK: /usr/lib64/R/lib/libRlapack.so
> >
> > locale:
> > [1] LC_CTYPE=en_US.UTF-
> > 8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8
> > [4] LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-
> > 8    LC_MESSAGES=en_US.UTF-8
> > [7] LC_PAPER=en_US.UTF-
> > 8       LC_NAME=C                  LC_ADDRESS=C
> > [10] LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8
> > LC_IDENTIFICATION=C
> >
> > attached base packages:
> > [1] stats     graphics  grDevices
> > utils     datasets  methods   base
> >
> > other attached packages:
> > [1] inline_0.3.14 magrittr_1.5
> >
> > loaded via a namespace (and not attached):
> > [1] compiler_3.4.1 tools_3.4.1    yaml_2.1.18    ulimit_0.0-3
> >
> > ______________________________________________
> > [hidden email] mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
> >
>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel