On 5/19/2006 10:55 AM, Duncan Murdoch wrote: > On 5/19/2006 10:37 AM, 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. > > Right, but the user would have seen the error, and can decide how to > recover from it. If trying to evaluate x again is the wrong thing to > do, the user is the one who would know that. > >> 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. >> >> 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. > > This is a very rare situation, so I agree putting in some slow way to > recover from an error is a bad idea. I think we should do the following: > > - fix substitute so it could be used to extract the promise expression > even if x lives in .GlobalEnv. (This can't happen for 2.3.1.) > > - add delayedAssignmentReset to repair x if that's preferred. (Is > this a reasonable addition to a patch release?) > > This won't leave promises alone in case of an error, but will make it > fairly easy for a user to recover using tryCatch.
I took a look at doing DelayedAssignmentReset, but haven't done it. It requires some tricky stuff (you can't evaluate the argument in the regular way, etc.) It also needs some thought: should you be able to reset a promise that isn't messed up in this way, so it evaluates its expression again? So I don't plan to do anything for now. If someone else wants to take it on, please do. Duncan Murdoch ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel