[Rd] delayedAssign and interrupts
Duncan Murdoch
murdoch at stats.uwo.ca
Sun May 21 23:00:26 CEST 2006
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
More information about the R-devel
mailing list