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?

Here's the code that causes this:

static SEXP forcePromise(SEXP e)
{
   if (PRVALUE(e) == R_UnboundValue) {
     SEXP val;
     if(PRSEEN(e))
       errorcall(R_GlobalContext->call,
                _("recursive default argument reference"));
     SET_PRSEEN(e, 1);
     val = eval(PRCODE(e), PRENV(e));
     SET_PRSEEN(e, 0);
     SET_PRVALUE(e, val);
   }
   return PRVALUE(e);
}

The idea is that you don't want to get into an infinite loop by having 
something like

f <- function(x = x)

or

delayedAssign(x, x)

so the PRSEEN bit is set before trying to evaluate the promise. 
However, if the eval() aborts it jumps right back up to the top level, 
the bit never gets reset to 0, and you get the spurious error message 
you saw.

I'll look into fixing this for 2.3.1.

Duncan Murdoch

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to