[Rd] [External] Re: stopifnot -- eval(*) inside for()

Tierney, Luke |uke-t|erney @end|ng |rom u|ow@@edu
Mon Apr 1 14:41:08 CEST 2019


On Mon, 1 Apr 2019, Martin Maechler wrote:

>>>>>> Suharto Anggono Suharto Anggono via R-devel
>>>>>>     on Sun, 31 Mar 2019 15:26:13 +0000 writes:
>
>    > Ah, with R 3.5.0 or R 3.4.2, but not with R 3.3.1, 'eval'
>    > inside 'for' makes compiled version behave like
>    > non-compiled version.
>
> Ah.. ... thank you for detecting that  " eval() inside for()" behaves
> specially  in how error message get a call or not.

Don't count on that remaining true indefinitely. The standard behavior
is better and we'll eventually get the case where 'eval' and a few
others are called to behave the same.

Best,

luke

> Let's focus only on this issue here.
>
> I'm adding a 0-th case to make even clearer what you are saying:
>
>  >  options(error = expression(NULL))
>  >  library(compiler)
>  >  enableJIT(0)
>
>  > f0 <- function(x) { x ; x^2 } ; f0(is.numeric(y))
>  Error in f0(is.numeric(y)) (from #1) : object 'y' not found
>  > (function(x) { x ; x^2 })(is.numeric(y))
>  Error in (function(x) { (from #1) : object 'y' not found
>  > f0c <- cmpfun(f0) ; f0c(is.numeric(y))
>
> so by default, not only the error message but the originating
> call is shown as well.
>
> However, here's your revealing examples:
>
>  > f <- function(x) for (i in 1) {x; eval(expression(i))}
>  > f(is.numeric(y))
>  > # Error: object 'y' not found
>  > fc <- cmpfun(f)
>  > fc(is.numeric(y))
>  > # Error: object 'y' not found
>
> I've tried more examples and did not find any difference
> between simple interpreted and bytecompiled code {apart
> from "keep.source=TRUE" keeping source, sometimes visible}.
> So I don't understand yet why you think the byte compiler plays
> a role.
>
> Rather the crucial difference seems  the error happens inside a
> loop which contains an explicit eval(.), and that eval() may
> even be entirely unrelated to the statement in which the error
> happens [above: The error happens when the promise 'x' is
> evaluated, *before* eval() is called at all].
>
>
>    > Is this accidental feature going to be relied upon?
>
>    [i.e.  *in  stopifnot() R code (which in R-devel and R 3.5.x has
>            had an eval() inside the for()-loop)]
>
> That is a good question.
> What I really like about the R-devel case:  We do get errors
> signalled that do *not* contain the full stopifnot() call.
>
> With the newish introduction of the `exprs = { ... ... }` variant,
> it is even more natural to have large `exprs` in a stopifnot() call,
> and when there's one accidental error in there, it's quite
> unhelpful to see the full stopifnot(..........) call {many lines
> of R code} obfuscating the one statement which produced the
> error.
>
> So it seems I am asking for a new feature in R,
> namely to temporarily say: Set the call to errors to NULL "in
> the following".
> In R 3.5.x, I had used withCallingHandlers(...) to achieve that
> and do even similar for warnings... but needed to that for every
> expression and hence inside the for loop  and the consequence
> was a relatively large slowdown of stopifnot()..  which
> triggered all the changes since.
>
> Whereas what we see here ["eval() inside for()"] is a cheap
> automatic suppression of 'call' for the "internal errors", i.e.,
> those we don't trigger ourselves via stop(simplError(...)).
>
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

-- 
Luke Tierney
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-tierney using uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu



More information about the R-devel mailing list