Re: stopifnot

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: stopifnot

R devel mailing list
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.

options(error = expression(NULL))
library(compiler)
enableJIT(0)
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

Is this accidental feature going to be relied upon?


"Details" section of 'stopifnot' documentation in current R 3.6.0 alpha (https://svn.r-project.org/R/branches/R-3-6-branch/src/library/base/man/stopifnot.Rd) has this.

  Since \R version 3.6.0, \code{stopifnot()} no longer handles potential
  errors or warnings (by \code{\link{tryCatch}()} etc) for each single
  expression but rather aims at using the correct
  \code{\link{sys.call}(<n>)} to get the most meaningful error message in
  case of an error.  This provides considerably less overhead.

I think part of the first sentence starting from "but rather" should be removed because it is not true.


The next paragraph:

  Since \R version 3.5.0, expressions \emph{are} evaluated sequentially,
  and hence evaluation stops as soon as there is a \dQuote{non-TRUE}, as
  indicated by the above conceptual equivalence statement.
  Further, when such an expression signals an error or
  \code{\link{warning}}, its \code{\link{conditionCall}()} no longer
  contains the full \code{stopifnot} call, but just the erroneous
  expression.

As I said earlier (https://stat.ethz.ch/pipermail/r-devel/2019-February/077386.html), the last sentence above is not entirely true. It may say something like:
Furher, when such an expression signals an error, stopifnot() in R 3.5.x makes its conditionCall() the erroneous expression, but no longer since R 3.6.0.


Is it OK that, for
do.call(stopifnot, list(exprs = expression())) ,
the whole expression object is taken as one?


End portion from running
example(stopifnot)
in R 3.5.0:
stpfnt> stopifnot(all.equal(pi, 3.141593),  2 < 2, all(1:10 < 12), "a" < "b")
Error in eval(ei, envir) : pi and 3.141593 are not equal:
  Mean relative difference: 1.102658e-07

To me, "in eval(*)" is rather surprising and annoying and doesn't add clarity. Yes, stop() gives the same. But, in this case, just "Error", like in R before version 3.5.0, feels better to me. If
stop(simpleError(msg, call = if(p <- sys.parent()) sys.call(p)))
were used in 'stopifnot', just "Error" would be given in this case.

--------------------------------------------

 wrote:

 Subject: Re: [Rd] stopifnot
 To: [hidden email]
 Date: Thursday, 7 March, 2019, 3:43 PM

[...]

As far as I can see, full stopifnot(...) call can only appear from an error that happens during evaluation of an argument of 'stopifnot'. Because the error is not raised by 'stopifnot', the call in the error has nothing to do with how 'n' is computed in sys.call(n-1) , or even with use of sys.call(n-1) itself.

if(n > 1) sys.call(n-1)
that I proposed previously was aimed to be like
sys.call(-1)
in 'stopifnot' in R 3.5.x. Negative number counts back from current frame. The value of 'n' is sys.nframe() or (sys.nframe()-3). In my patch, stopifnot(exprs=*) drives stopifnot(...) call via 'eval'. I found that frames were generated for
stopifnot (exprs) -> eval -> eval (.Internal) -> stopifnot (...)
From stopifnot (...) , reaching stopifnot (exprs) takes 3 steps back.


[...]

options(error = expression(NULL))
library(compiler)
enableJIT(0)
f <- function(x) for (i in 1) x
f(is.numeric(y))
# Error: object 'y' not found
fc <- cmpfun(f)
fc(is.numeric(y))
# Error in fc(is.numeric(y)) : object 'y' not found

The above illustrates what happens in current 'stopifnot' without 'withCallingHandlers' or 'tryCatch'. For error during 'for', non-compiled and compiled versions are different. It surprised me.

[...]


With my revised patch, the 'else' clause for 'cl' gives
call("expression", exprs) .
For
do.call(stopifnot, list(exprs = expression())) ,
the whole expression object is taken as one.

do.call(stopifnot, list(exprs = expression(1==1, 2 < 1, stop("NOT GOOD!\n"))))
Error in do.call(stopifnot, list(exprs = expression(1 == 1, 2 < 1, stop("NOT GOOD!\n")))) :
  expression(1 == 1, 2 < 1, stop("NOT GOOD!\n")) are not all TRUE

To be the same as in R 3.5.x, the 'else' can be
as.call(c(quote(expression), as.expression(exprs)))

--------------------------------------------
On Wed, 6/3/19, Martin Maechler <[hidden email]> wrote:

Subject: Re: [Rd] stopifnot

r-project.org
Cc: "Martin Maechler" <[hidden email]>
Date: Wednesday, 6 March, 2019, 3:50 PM

>>>>> Martin Maechler
>>>>>    on Tue, 5 Mar 2019 21:04:08 +0100 writes:

>>>>> Suharto Anggono Suharto Anggono
>>>>>    on Tue, 5 Mar 2019 17:29:20 +0000 writes:

[...]

    >> After thinking again, I propose to use
    >>         stop(simpleError(msg, call = if(p <- sys.parent()) sys.call(p)))

    > That would of course be considerably simpler indeed,  part "2 a" of these:

    >> - It seems that the call is the call of the frame where stopifnot(...) is evaluated. Because that is the correct context, I think it is good.
    >> - It is simpler and also works for call that originally comes from stopifnot(exprs=*) .

    >> - It allows shortcut ('assert') to have the same call in error message as stopifnot(exprs=*) .

    > That may be another good reason in addition to code simplicity.

    > I will have to see if this extra simplification does not loose
    > more than I'd want.


    >> Another thing: Is it intended that
    >> do.call("stopifnot", list(exprs = expression()))
    >> evaluates each element of the expression object?

    > ??  I really don't know.  Even though such a case looks
    > "unusual" (to say the least), in principle I'd like that
    > expressions are evaluated sequentially until the first non-TRUE
    > result.  With a concrete example, I do like what we have
    > currently in unchanged R-devel, but also in R 3.5.x, i.e., in
    > the following, not any "NOT GOOD" should pop up:

    >> stopifnot(exprs = expression(1==1, 2 < 1, stop("NOT GOOD!\n")))
    > Error: 2 < 1 is not TRUE
    >> do.call(stopifnot, list(exprs = expression(1==1, 2 < 1, stop("NOT GOOD!\n"))))
    > Error in do.call(stopifnot, list(exprs = expression(1 == 1, 2 < 1, cat("NOT GOOD!\n")))) :
    > 2 < 1 is not TRUE
    >>

    > Hmm, it seems I do not understand what you ask above in your
    > "Another thing: .."


    >> If so, maybe add a case for 'cl', like
    >>         else if(is.expression(exprs))
    >>         as.call(c(quote(expression), exprs))

    > that seems simple indeed, but at the moment, I cannot see one example
    > where it makes a difference ... or then I'm "blind" .. ???

    > Best,
    > Martin

Some more testing of examples lead me to keep the more
sophisticated "computation" of 'n'  for the  sys.call(n-1).

Main reason:  If one of the expression is not all TRUE, I really
don't want to see the full 'stopifnot(....)' call in the printed
error message.
I do want to encourage that  stopifnot()  asserts many things
and so its own call should really not be shown.

Also I really wanted to commit something, notably also fixing
the  stopifnot(exprs = T)  bug,  so R-devel (rev >= 76203 ) now
contains a simpler and much faster  stopifnot() than previously
[and than the R 3.5.x series].

I agree that the final decisions on getting a call (or not --
which was a very good idea by you!) and which parent's call
should be used  may deserve some future tinkering..

Thank you again, Suharto Anggono,
[[elided Yahoo spam]]


Martin

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: stopifnot -- eval(*) inside for()

Martin Maechler
>>>>> 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.
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(...)).

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

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

Tierney, Luke
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(...)).
>
> ______________________________________________
> [hidden email] 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:   [hidden email]
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: stopifnot

Martin Maechler
In reply to this post by R devel mailing list
>>>>> Suharto Anggono Suharto Anggono via R-devel
>>>>>     on Sun, 31 Mar 2019 15:26:13 +0000 writes:

 [.............]
 [........ "eval() inside for()" not giving call in error message .....]
 [.............]

    > "Details" section of 'stopifnot' documentation in current R 3.6.0 alpha
    > (https://svn.r-project.org/R/branches/R-3-6-branch/src/library/base/man/stopifnot.Rd)
    > has this.

    >   Since \R version 3.6.0, \code{stopifnot()} no longer handles potential
    >   errors or warnings (by \code{\link{tryCatch}()} etc) for each single
    >   expression but rather aims at using the correct
    >   \code{\link{sys.call}(<n>)} to get the most meaningful error message in
    >   case of an error.  This provides considerably less overhead.

    > I think part of the first sentence starting from "but rather" should be removed because it is not true.

You are right that it is not accurate... I'll modify it,
including keeping the  "considerably less overhead"
which had been one important reason for changing from 3.5.x to
the current version.

    > The next paragraph:

    >   Since \R version 3.5.0, expressions \emph{are} evaluated sequentially,
    >   and hence evaluation stops as soon as there is a \dQuote{non-TRUE}, as
    >   indicated by the above conceptual equivalence statement.
    >   Further, when such an expression signals an error or
    >   \code{\link{warning}}, its \code{\link{conditionCall}()} no longer
    >   contains the full \code{stopifnot} call, but just the erroneous
    >   expression.

    > As I said earlier (https://stat.ethz.ch/pipermail/r-devel/2019-February/077386.html), the last sentence above is not entirely true.

You are right to some degree:  That really was true for R 3.5.x,
but is no longer entirely accurate.

It is still true currently interestingly thanks to the "eval() in for()"
behavior that the error/warning message is most of the time only
about the relevant part and not mentioning the full stopifnot(..) call.


    > It may say something like:
    > Further, when such an expression signals an error, stopifnot() in R 3.5.x makes its conditionCall() the erroneous expression, but no longer since R 3.6.0.


    > Is it OK that, for
    > do.call(stopifnot, list(exprs = expression())) ,
    > the whole expression object is taken as one?

You are right; that's not so nice.
On one hand, this is fine, as there is nothing not TRUE :

   > stopifnot()          
   > stopifnot(exprs = {})

but here,

   > do.call(stopifnot, list(exprs = expression()))
   Error in do.call(stopifnot, list(exprs = expression())) :
     expression() are not all TRUE

I'm about to commit a version [mostly from your suggestions],
where the above do.call() works as well.

    > End portion from running
    > example(stopifnot)
    > in R 3.5.0:

    stpfnt> stopifnot(all.equal(pi, 3.141593),  2 < 2, all(1:10 < 12), "a" < "b")
    > Error in eval(ei, envir) : pi and 3.141593 are not equal:
    >   Mean relative difference: 1.102658e-07

    > To me, "in eval(*)" is rather surprising and annoying and doesn't add clarity. Yes, stop() gives the same. But, in this case, just "Error", like in R before version 3.5.0, feels better to me. If
    > stop(simpleError(msg, call = if(p <- sys.parent()) sys.call(p)))
    > were used in 'stopifnot', just "Error" would be given in this case.

And you are right again... in my current version I do use your

   stop(simpleError(msg, call = if(p <- sys.parent()) sys.call(p)))

and that does solve the above.

Martin

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

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

Martin Maechler
In reply to this post by Tierney, Luke
>>>>> Tierney, Luke
>>>>>     on Mon, 1 Apr 2019 12:41:08 +0000 writes:

    > 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

Yes, Suharto did indeed mention that it may not be a good idea
to rely on that behavior, and I did agree ... though my
agreement was a bit buried in other stuff.

Note that I have been asking if this "accidental" but internally
consistent behavior for the current situation, could not be made
a feature that the user can ask for ... without having to use a
handler (which had been a real slowdown when used inside
stopifnot() in R 3.5.3) :


  [................]
  [................]

    >> 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(simpleError(...)).

So, for me as programmeR, it would be nice to be able to ask for
"this" behavior explicitly in a special case as here, where
"no-call" error messages are preferable .. because the call can
be really large and is known to be  "almost surely" distracting
rather than helpful.

Martin

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: stopifnot -- eval(*) inside for()

R devel mailing list
In reply to this post by Martin Maechler
With
f <- function(x) for (i in 1) x
fc <- cmpfun(f)
(my previous example), error message of
fc(is.numeric(y))
shows the originating call as well, while error message of
f(is.numeric(y))
doesn't. Compiled version behaves differently.

Even with
f <- function(x) for (i in 1) {x; eval(expression(i))}
fc <- cmpfun(f)
, error message of
fc(is.numeric(y))
shows the originating call in R 3.3.1.


As I see, error message only has one line of call. If the deparsed call spans more than one line, the rest is not shown.


In 'stopifnot' in R 3.5.x, each is wrapped in 'tryCatch' which is wrapped again in 'withCallingHandlers'. Just one wrapping may be enough. The 'withCallingHandlers' construct in 'stopifnot' in R 3.5.x has no effect anyway, as I said before (https://stat.ethz.ch/pipermail/r-devel/2019-February/077386.html). Also, 'tryCatch' (or 'withCallingHandlers' ...) can wrap the entire 'for' loop. The slowdown can be less than in R 3.5.x.

--------------------------------------------
On Mon, 1/4/19, Martin Maechler <[hidden email]> wrote:

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

 Cc: [hidden email]
 Date: Monday, 1 April, 2019, 5:00 PM
 
>>>>> 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.
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(...)).

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel