From maechler at stat.math.ethz.ch  Sat May 20 17:41:05 2017
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Sat, 20 May 2017 17:41:05 +0200
Subject: [Rd] stopifnot() does not stop at first non-TRUE argument
In-Reply-To: <CAF8bMcYUT9qZSJq6hppg6V_=BQAdqyx+zyXnvSUZbpQdB+hdtg@mail.gmail.com>
References: <812904062.672054.1495124829132.ref@mail.yahoo.com>
 <812904062.672054.1495124829132@mail.yahoo.com>
 <22814.58779.91894.396576@stat.math.ethz.ch>
 <CAF8bMcYUT9qZSJq6hppg6V_=BQAdqyx+zyXnvSUZbpQdB+hdtg@mail.gmail.com>
Message-ID: <22816.25489.288803.850541@stat.math.ethz.ch>

>>>>> William Dunlap <wdunlap at tibco.com>
>>>>>     on Fri, 19 May 2017 09:30:42 -0700 writes:

    > While you are fiddling with stopifnot(), please consider changing the form
    > of the error thrown so that it includes the caller's call.  The change
    > would be from something like
    >   stop( <<the message>> )
    > to
    >   stop(simpleError( <<the message>>, sys.call(-1)))

    > For the following code
    >   f <- function(x, y) {
    >     stopifnot(x > y)
    >     x - y
    >   }
    >   g <- function(x, y, z) {
    >      c(f(x, y), f(y, z))
    >   }
    >   g(6,3,4)

    > you would see
    >   Error in f(y, z) : x > y is not TRUE
    > instead of the less informative
    >   Error: x > y is not TRUE

well, yes, I have been fiddling .. ;-)

and your proposal above is quite remarkable!
I hadn't been aware of (the consequence of) this possibility.

I will do that change in addition to the planned ones, just to
make the changes slightly more modular.
(It will need a change in   tests/isas-tests.Rout.save  as
indeed, the _messages_ of non-toplevel  stopifnot() calls will
change too.
This may affect package checks check for the _wording_ of
stopifnot error messages [which may not be the best idea
.. though understandable for regression checks].

Martin


    > Bill Dunlap
    > TIBCO Software
    > wdunlap tibco.com

    > On Fri, May 19, 2017 at 5:31 AM, Martin Maechler <maechler at stat.math.ethz.ch
    >> wrote:

    >> >>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at r-project.org>
    >> >>>>>     on Thu, 18 May 2017 16:27:09 +0000 writes:
    >> 
    >> >> From an example in
    >> 
    >> >> http://www.uni-muenster.de/ZIV.BennoSueselbeck/s-html/
    >> helpfiles/nargs.html
    >> >> , number of arguments in '...' can be obtained by
    >> 
    >> > (function(...)nargs())(...) .
    >> 
    >> neat and good.  Though really is not exactly "well readable".
    >> 
    >> In the mean time, there is   ...length()   in R-devel [somewhat
    >> experimentally]
    >> 
    >> > I now realize that sys.call() doesn't expand '...' when
    >> > the function is called with '...'. It just returns the call as is.
    >> yes.
    >> > If 'stopifnot' uses sys.call() instead of
    >> > match.call() , the following example behaves improperly:
    >> 
    >> > g <- function(...) stopifnot(...)
    >> > g(TRUE, FALSE)
    >> 
    >> Indeed.  Very improperly (it does not stop).
    >> 
    >> However, calling stopifnot() with a '...' passed from above is
    >> not a very good idea anyway, because stopifnot has to assume it
    >> is called with explicit expressions.
    >> Hence we have
    >> 
    >> > g <- function(...) stopifnot(...) ;  g(1 == 1, 3 < 1)
    >> Error: ..2 is not TRUE
    >> 
    >> {and to "fix" this, e.g., with an extra optional argument} would
    >> lead to more complications  which I really think we do not want}.
    >> 
    >> But the example does show we should keep match.call().
    >> Martin
    >> 
    >> > --------------------------------------------
    >> > On Thu, 18/5/17, Martin Maechler
    >> > <maechler at stat.math.ethz.ch> wrote:
    >> 
    >> >  Subject: Re: [Rd] stopifnot() does not stop at first
    >> > non-TRUE argument
    >> 
    >> >  Cc: r-devel at r-project.org Date: Thursday, 18 May, 2017,
    >> > 3:03 PM
    >> 
    >> >>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at
    r-project.org> 
    >> >>>>>     on Tue, 16 May 2017 16:37:45 +0000 writes:
    >> 
    >> >> switch(i, ...)  extracts 'i'-th argument in '...'. It is
    >> >> like eval(as.name(paste0("..", i))) .
    >> 
    >> > Yes, that's neat.
    >> 
    >> > It is only almost the same: in the case of illegal 'i' the
    >> > switch() version returns invisible(NULL)
    >> 
    >> > whereas the version we'd want should signal an error,
    >> > typically the same error message as
    >> 
    >> >> t2 <- function(...) ..2 t2(1)
    >> >   Error in t2(1) (from #1) : the ... list does not contain
    >> > 2 elements
    >> >>
    >> 
    >> 
    >> >> Just mentioning other things: - For 'n', n <- nargs() can
    >> >> be used.
    >> 
    >> > I know .. [in this case, where '...' is the only formal
    >> > argument of the function]
    >> 
    >> >> - sys.call() can be used in place of match.call() .
    >> 
    >> > Hmm... in many cases, yes.... notably, as we do *not* want
    >> > the argument names here, I think you are right.
    >> 
    >> > ______________________________________________
    >> > R-devel at r-project.org mailing list
    >> > https://stat.ethz.ch/mailman/listinfo/r-devel
    >> 
    >> ______________________________________________
    >> R-devel at r-project.org mailing list
    >> https://stat.ethz.ch/mailman/listinfo/r-devel
    >> 

    > [[alternative HTML version deleted]]



[Rd] stopifnot() does not stop at first non-TRUE argument
Martin Maechler