Bug 15958 - super assignment <<- fails in call-back functions
Summary: super assignment <<- fails in call-back functions
Status: ASSIGNED
Alias: None
Product: R
Classification: Unclassified
Component: Language (show other bugs)
Version: R 3.1.1
Hardware: x86_64/x64/amd64 (64-bit) Linux-Fedora
: P5 major
Assignee: Michael Lawrence
URL:
Depends on:
Blocks:
 
Reported: 2014-09-03 11:32 UTC by Thomas Petzoldt
Modified: 2014-09-05 21:15 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Petzoldt 2014-09-03 11:32:33 UTC
While working with closures in deSolve we have found unexpected behaviour
in R 3.1.0 and R 3.1.1 and R devel, while it was still correct in R
3.0.3. 

The symptom is that in R functions back-called from the C level 
super assignments (<<-) of unmodified variables lead to "references"
instead of copies:

- the bug occurs in several packages including nlm in base.
- reproducible on Windows x86, x64 and Fedora x64.


R 3.0.3: x.old == x.old1  ! correct

R 3.1.1: x.old == x       ! wrong


Reproducible example:
=====================

f <- function(x, a) {
    cat(x[1], x.old[1], x.old1[1], (x.old1 == x.old)[1], "\n")
    x.old   <<- x          # "reference to x"
    x.old1  <<- x * 1      #  copy of x
    sum((x-a)^2)
}

x.old <- x.old1 <- 0
A <- nlm(f, c(10,10), a = c(3,5))


Output in R < 3.1.0
-------------------

10        0        0       TRUE 
10       10       10       TRUE 
10.00001 10       10       TRUE 
10       10.00001 10.00001 TRUE 
...
3 2.9997 2.9997 TRUE 
3 3 3 TRUE 



Output in R >= 3.1.0
-------------------

10        0        0       TRUE 
10       10       10       TRUE 
10.00001 10.00001 10       FALSE 
10       10       10.00001 FALSE 
...
3         3        2.9997  FALSE 
3         3        3       TRUE
Comment 1 Michael Lawrence 2014-09-03 12:57:03 UTC
The code invoking the callbacks is modifying the arguments in place. While it's always been necessary to duplicate in these situations, R < 3.1 would duplicate internally, so these bugs were never exposed. It would be helpful if you could tell us the packages you've found besides nlm that are affected.
Comment 2 Luke Tierney 2014-09-03 13:05:16 UTC
If C callback code wants to be able to modify the argument without duplicating it needs to use MAYBE_REFERENCED to make sure doing so is safe. For now, MAYBE_REFERENCED will always be true after an argument had been passed to a function, and so duplication will always occur, but changes in the next few months may allow safe duplicaton to occur in some cases. Whether the savings are really worth while is another question.
Comment 3 Luke Tierney 2014-09-03 13:36:30 UTC
(In reply to Luke Tierney from comment #2)
> If C callback code wants to be able to modify the argument without
> duplicating it needs to use MAYBE_REFERENCED to make sure doing so is safe.
> For now, MAYBE_REFERENCED will always be true after an argument had been
> passed to a function, and so duplication will always occur, but changes in
> the next few months may allow safe duplicaton to occur in some cases.
> Whether the savings are really worth while is another question.

make that '... safe _modification_ ...'
Comment 4 Thomas Petzoldt 2014-09-03 14:29:47 UTC
We have seen this in deSolve's ODEPACK functions (call_lsoda.c) while the call of the Runge-Kutta solvers seem to be unaffected (function void derivs in rk_util.c).

Another function that Karline detected was nls.lm from minpack.lm

Functions optim and integrate (base R) have been OK.
Comment 5 Michael Lawrence 2014-09-05 21:15:55 UTC
Thanks, I've just commited a simple fix for nlm(), and I will work with the authors of those other packages to do the same.