[prev in list] [next in list] [prev in thread] [next in thread] 

List:       r-devel
Subject:    Re: [Rd] Array changing address unexpectedly
From:       luke-tierney () uiowa ! edu
Date:       2017-11-12 19:38:43
Message-ID: alpine.OSX.2.20.1711121326510.53256 () lukes-air
[Download RAW message or body]

A simpler version with annotation:

library(pryr)

data <- 1:5          # new allocation, referenced from one variable

add <- address(data)

data[1] <- 6L        # only one reference; don't need to duplicate

add == address(data) # TRUE

print(data)          # inside the print call the local variable also references
                      # the object, so there are two references

data[1] <- 7L        # there have been two references to the object, so need
                      # to duplicate

add == address(data) # FALSE

R objects are supposed to be immutable, so conceptually
assignments create a new object. If R is sure it is safe to do
so, it will avoid making a copy and re-use the original
object. In the first assignment there is only one reference to
the object, the variable data, and it is safe to re-use the
object, so the address of the new value of `data` is the same as
the address of the old value. It would not be safe to do this if
the assignment happened inside print(), since there are then two
references -- the original variable and the local variable for
the argument. R currently doesn't have enough information to know
that there is only one reference after the call to print()
returns, so it has to be safe and make a copy, and the new value
has a different address than the old one. R may be able to be
less conservative in the future, but for now it cannot.

[As an exercise you can try to work out why the calls to
address() don't play a role in this.]

As a rule you shouldn't need to worry about addresses, and R might
make changes in the future that would: cause the address in this
version of the example to change on the first assignments; cause the
address on the second assignment to not change; cause the information
provided by pryr to be inaccurate or misleading; result in the use of
a tool like pryr::address to change the internal structure of the
object.

Best,

luke

On Sun, 12 Nov 2017, lille stor wrote:

> Hi David,
> 
> Thanks for the correction concerning the "else" issue.
> 
> Taking your code and removing some lines (to increase readability):
> 
> 
> library(pryr)
> 
> data <- array(dim = c(5))
> for(x in 1:5)
> {
> data[x] <- as.integer(x * 2)
> }
> 
> #print(data)
> 
> add = address(data)
> for(x in 1:5)
> {
> data[x] <- as.integer(0)
> }
> 
> if (add == address(data))
> {
> print("Address did not change")
> } else {
> print("Address changed")
> }
> 
> 
> If one runs this code everything works as expected, i.e. message "Address did not \
> change" is printed. However, if one uncomments line "#print(data)", message \
> "Address is changed" is printed instead. Any idea why this happens as it is a bit \
> counter-intuitive? Is it something to do with some kind of lazy-evaluation \
> mechanism R has that makes the array to be filled-up only when needed (in this \
> case, when printing it) thus changing the array's address? 
> Thank you once more!
> 
> 
> 
> 
> 
> Sent: Sunday, November 12, 2017 at 6:02 PM
> From: "David Winsemius" <dwinsemius@comcast.net>
> To: "lille stor" <lille.stor@gmx.com>
> Cc: r-devel@r-project.org
> Subject: Re: [Rd] Array changing address unexpectedly
> > On Nov 12, 2017, at 8:47 AM, lille stor <lille.stor@gmx.com> wrote:
> > 
> > Hi,
> > 
> > Given the following R code:
> > 
> > library(pryr)
> > 
> > data <- array(dim = c(5))
> > 
> > for(x in 1:5)
> > {
> > data[x] <- as.integer(x * 2)
> > }
> > 
> > add = address(data) # save address of "data"
> > 
> > for(x in 1:5)
> > {
> > data[x] <- as.integer(0)
> > }
> > 
> > if (add == address(data))
> > {
> > print("Address did not change")
> > }
> > else
> > {
> > print("Address changed")
> > }
> > 
> > If one runs this code, message "Address changed" is printed. However, if one \
> > comments line "data[x] <- as.integer(0)" the address of "data" does not change \
> > and message "Address did not change" is printed instead. Why? The datatype of the \
> > array should not change with this line and hence no need for R to convert the \
> > array to a different type (and have the array's address changing in the process).
> 
> I'm guessing you didn't take note of the error message:
> 
> > else
> Error: unexpected 'else' in " else"
> 
> It's always good practice to investigate errors. The else function needs to come \
> immediately after the "{". 
> Here's a more complete test of what I take to be your question:
> 
> library(pryr)
> 
> data <- array(dim = c(5))
> add = address(data)
> for(x in 1:5)
> {
> data[x] <- as.integer(x * 2)
> }
> if (add == address(data))
> {
> print("Address did not change")
> } else {
> print("Address changed")
> }
> 
> 
> data <- array(dim = c(5)) # reset
> add = address(data)
> for(x in 1:5)
> {
> data[x] <- as.integer(0)
> }
> 
> if (add == address(data))
> {
> print("Address did not change")
> } else {
> print("Address changed")
> }
> 
> # changes in both situations.
> 
> 
> > 
> > Thank you!
> > 
> > ______________________________________________
> > R-devel@r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> David Winsemius
> Alameda, CA, USA
> 
> 'Any technology distinguishable from magic is insufficiently advanced.' -Gehm's \
> Corollary to Clarke's Third Law 
> 
> 
> 
> 
> 
> ______________________________________________
> R-devel@r-project.org 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:   luke-tierney@uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic