From simon.urbanek at r-project.org  Wed Oct 18 03:20:06 2006
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Tue, 17 Oct 2006 21:20:06 -0400
Subject: [Rd] Error condition in evaluating a promise
In-Reply-To: <6phvemixy1u.fsf@gopher4.fhcrc.org>
References: <0359A469-1F7D-4CEF-A408-CCB185D5F90E@r-project.org>
	<6phvemixy1u.fsf@gopher4.fhcrc.org>
Message-ID: <1BF71ED7-1F46-43F3-83BE-D353FC410BA6@r-project.org>


On Oct 17, 2006, at 8:33 PM, Martin Morgan wrote:

>> delayMe <- function() {
> +     if (failed) {
> +         delayedAssign("x", delayMe(), assign.env=topenv())
> +         stop("init me!")
> +     } else foo
> + }
>>
>> failed <- TRUE
>> foo <- "is me"
>> delayedAssign("x", delayMe())
>> x
> Error in delayMe() : init me!
>> x
> Error in delayMe() : init me!
>> failed <- FALSE
>> x
> [1] "is me"
>
> ??
>

This works only because you assigned both x and the delayMe function  
to the global environment. This won't work in any other case (and no,  
I didn't want to use this in the global environment - you shouldn't  
be trashing it anyway ;)).

Of course you can recursively re-install the promise, but that's  
beside the point.
FWIW a general solution re-installing the promise could look like this:
local({ ae<-parent.env(environment()); d<-function() {print 
(environment()); if(failed) { delayedAssign("x", d(), assign.env=ae);  
stop("init me!") } else foo}; delayedAssign("x", d(),assign.env=ae)})

However in my particular case the whole point of using a promise is  
that I'm dealing with a sealed environment (namespace) so you cannot  
re-install delayedAssign again (it will fail because the binding is  
locked). If the promise worked as I envision, re-installing  
delayedAssign would be unnecessary, because the promise is already in  
place and will stay there until the evaluation is successful.

Cheers,
Simon

> Simon Urbanek <simon.urbanek at r-project.org> writes:
>
>> Is there a way to raise an error condition when a promise is
>> evaluated such that is can be evaluated again? Right now strange
>> things happen when the evaluation fails:
>>
>>> delayedAssign("x", if (failed) stop("you have to initialize me
>> first!") else foo)
>>> foo <- "I'm foo"
>>> failed<-TRUE
>>> x
>> Error: you have to initialize me first!
>>> x
>> Error: recursive default argument reference
>>
>> ^^-- from now on x is completely unusable - it has no value (i.e.
>> cannot be passed to any function) and yet won't be evaluated again
>>
>>> failed<-FALSE
>>> x
>> Error: recursive default argument reference
>>> delayedAssign("x", if (failed) stop("you have to initialize me
>> first!") else foo)
>>> x
>> [1] "I'm foo"
>>
>> I'd expect something like
>>> failed<-TRUE
>>> x
>> Error: you have to initialize me first!
>>> x
>> Error: you have to initialize me first!
>>> failed<-FALSE
>>> x
>> [1] "I'm foo"
>>
>> Is there a way to achieve that? Intuitively I'd think that this is
>> the desired behavior, because currently the promise is sort of
>> 'broken' after an error (AFAICT the behavior is not documented
>> anywhere) - but then, I wasn't messing with promises until now...
>>
>> Thanks,
>> Simon
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>
> -- 
> Martin T. Morgan
> Bioconductor / Computational Biology
> http://bioconductor.org
>
>




[Rd] Error condition in evaluating a promise
Simon Urbanek