From rdpeng at gmail.com  Fri May 19 16:56:44 2006
From: rdpeng at gmail.com (Roger D. Peng)
Date: Fri, 19 May 2006 10:56:44 -0400
Subject: [Rd] delayedAssign and interrupts
In-Reply-To: <Pine.LNX.4.64.0605190920520.9980@nokomis.stat.uiowa.edu>
References: <446DCE07.2080504@gmail.com> <446DD2F8.5060900@stats.uwo.ca>
	<Pine.LNX.4.64.0605190920520.9980@nokomis.stat.uiowa.edu>
Message-ID: <446DDCAC.5040108@gmail.com>



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/



[Rd] delayedAssign and interrupts
Roger D. Peng