[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