From luke at stat.uiowa.edu  Wed Oct 18 21:04:07 2006
From: luke at stat.uiowa.edu (Luke Tierney)
Date: Wed, 18 Oct 2006 14:04:07 -0500 (CDT)
Subject: [Rd] Error condition in evaluating a promise
In-Reply-To: <8332D09D-AAE2-4892-94DE-64E2AA4509EF@r-project.org>
References: <0359A469-1F7D-4CEF-A408-CCB185D5F90E@r-project.org>
	<6phvemixy1u.fsf@gopher4.fhcrc.org> <6phvemiuw3r.fsf@gopher4.fhcrc.org>
	<9AE19AAE-9CAD-4697-82DC-07724445114C@r-project.org>
	<m2d58psl5d.fsf@ziti.local>
	<5EB2115D-9911-4268-85FA-9AB03F0D9009@r-project.org>
	<45365539.9050106@fhcrc.org> <4536618D.9070409@gmail.com>
	<8332D09D-AAE2-4892-94DE-64E2AA4509EF@r-project.org>
Message-ID: <Pine.LNX.4.64.0610181349000.21388@nokomis.stat.uiowa.edu>

On Wed, 18 Oct 2006, Simon Urbanek wrote:

>
> On Oct 18, 2006, at 1:17 PM, Roger D. Peng wrote:
>
>> I've encountered a (I think) related problem when using promises to
>> load relatively large datasets.  For example something like
>>
>> delayedAssign("x", getBigDataset())
>>
>> runs into the same problem if you hit Ctrl-C while 'x' is being
>> evaluated for the first time.  Afterwards, there's no way to
>> retrieve the dataset associated with 'x'.
>>
>> Active bindings work in this case, but the problem is that I
>> usually only want to load a large dataset once.
>>
>
> I agree. There are basically a few options AFAICS:
> 1) document in delayedAssign that error conditions during evaluation
> will lead to unusable/unrecoverable state of the promise and add a
> note discouraging the use of promises in R code (as they were never
> meant for that)
> 2) reset PRSEEN on error in eval of the promise code (probably
> expensive as it would apply to every promise)

Definitely not an option as you would need to set up to catch the
error at that point ant that is currently _very_ expensive.

> 3) optionally add a flag to promises created by delayedAssign such
> that those can be distinguished and handled separately (e.g. don't
> set PRSEEN, or install an error handler before evaluation to reset
> PRSEEN). This would not affect the internal use of promises and thus
> would have no impact on speed. It would, however, make them more robust.

Doesn't really solve the problem because delayedAssign isn't the only
way to get into this pickle.  The current implementation makes sense
if promises cannot outlive the calls that create them, but with
lexical scope that is not the case. Here is an artificial example:

     > f<-function(x) function() x
     > g <- f(1)
     > g()
     [1] 1
     > g <- f(stop("foo"))
     > g()
     Error in g() : foo
     > g()
     Error in g() : recursive default argument reference

There may be a fix but it won't be a quick fix, unfortunately.

> 4) add a function that will reset a 'rogue' promise (e.g.
> recoverDelayed(sym, env)) which could be used in a custom error
> handler in the promise code. This is basically poor man's version of 3)

Might be sueful as a debugging aid but I'd be nervous about using it
in production code.

> Personally I would vote for 3), but I can see the arguments for 1).

I'd prefer 1 until we have a chance to think this through more
carefully.  Given that R has side effects it isn't clear that marking
promises as unevaluated if they did not complete their evaluation (but
may have completed part of it) is clearly preferable to treating them
as evaluated if they haven't completed all their evaluation.

Best,

luke

-- 
Luke Tierney
Chair, Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:      luke at stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu




[Rd] Error condition in evaluating a promise
Luke Tierney