delayedAssign and interrupts
Luke Tierney wrote:
On Fri, 19 May 2006, Duncan Murdoch wrote:
On 5/19/2006 9:54 AM, Roger D. Peng wrote:
I noticed something recently that I thought was odd:
delayedAssign("x", { Sys.sleep(5); 1 })
x ## Hit Ctrl-C within the first second or 2
gives me:
delayedAssign("x", { Sys.sleep(5); 1 })
x ## Hit Ctrl-C within the first second or two
x
Error: recursive default argument reference
My only problem here is that now I'm stuck---there's no way to recover whatever 'x' was supposed to be (i.e. 1). In reality, I want 'x' to be a promise to load a moderately large data object. But if I (or a user) Ctrl-C's during the load I'll have to start from scratch. Is there anyway to recover the promise (or the value of the expression) in case of an interrupt?
I don't know of one. Normally substitute(x) is supposed to retrieve the promise expression, but by a strange quirk of history, it does not work when x is in .GlobalEnv. I'd say the behaviour you're seeing is a bug. If I do
x <- 2
x <- {Sys.sleep(1); 1} # Break before complete
x
[1] 2 nothing is changed about x. I would think the same thing should happen when x is a promise: if the evaluation of the promised expression fails, the promise should not be changed.
I don't think this is a clear as you make it out--given that these uses of promises often have side effects, and some of those side effects may have occurred prior to an error, it isn't clear that pretending like no evaluation had happened is the right way to go. It should not be too hard to write a delayedAssignmentReset function if that is really useful; alternatively a user of delayedAssign should be able to arrange via tryCatch to chatch interrupts and re-install the delayed assignment if one occurs.
This was my original thought, and I think it would be possible to use tryCatch to reinstall the delayed assignment. However, I couldn't figure out how to have the reinstalled expression to be able to catch interrupts without getting into some infinite expression.... Perhaps I need to investigate it further.
It might not be a bad idea for us to look into the promise evaluation internals and see if we should/can separate the promise black-holing from detection of recursive default argument references to get more reasonable error messages in these situations and maybe allow resetting more gnerally. But anything done here had better keep efficiency in mind since this is prety core to R function call evaluation. I may try to look into this when I get back to workign on R internals. luke
Roger D. Peng | http://www.biostat.jhsph.edu/~rpeng/