I see in the archives that the attachment cannot pass.
So, here is the code:
8<----
stopifnot_new <- function (...)
{
    mc <- match.call()
    n <- length(mc)-1
    if (n == 0L)
        return(invisible())
    Dparse <- function(call, cutoff = 60L) {
        ch <- deparse(call, width.cutoff = cutoff)
        if (length(ch) > 1L)
            paste(ch[1L], "....")
        else ch
    }
    head <- function(x, n = 6L) x[seq_len(if (n < 0L) max(length(x) +
        n, 0L) else min(n, length(x)))]
    abbrev <- function(ae, n = 3L) paste(c(head(ae, n), if (length(ae) >
        n) "...."), collapse = "\n  ")
    pfr <- parent.frame()
    for (i in 1L:n) {
        cl.i <- mc[[i + 1L]]
        r <- eval(cl.i, pfr)
        if (!(is.logical(r) && !anyNA(r) && all(r))) {
            msg <- if (is.call(cl.i) && identical(cl.i[[1]], quote(all.equal)) 
&&
                (is.null(ni <- names(cl.i)) || length(cl.i) == 3L ||
                    length(cl.i <- cl.i[!nzchar(ni)]) == 3L))
                sprintf(gettext("%s and %s are not equal:\n  %s"),
                    Dparse(cl.i[[2]]), Dparse(cl.i[[3]]), abbrev(r))
            else sprintf(ngettext(length(r), "%s is not TRUE", "%s are not all 
TRUE"),
                Dparse(cl.i))
            stop(msg, call. = FALSE, domain = NA)
        }
    }
    invisible()
}
8<----

Best,
Serguei.

Le 15/05/2017 à 12:48, Serguei Sokol a écrit :
Hello,

I am a new on this list, so I introduce myself very briefly:
my background is applied mathematics, more precisely scientific calculus
applied for modeling metabolic systems, I am author/maintainer of
few packages (Deriv, rmumps, arrApply).

Now, on the subject of this discussion, I must say that I don't really 
understand
Peter's argument:

    >>> To do it differently, you would have to do something like
    >>>
    >>> dots <- match.call(expand.dots=FALSE)$...
    >>>
    >>> and then explicitly evaluate each argument in turn in the caller
    >>> frame. This amount of nonstandard evaluation sounds like it would
    >>> incur a performance penalty, which could be undesirable.
The first line of the current stopifnot()
n <- length(ll <- list(...))
already evaluates _all_ of the arguments
in the caller frame. So to do the same only
on a part of them (till the first FALSE or NA occurs)
cannot be more penalizing than the current version, right?

I attach here a slightly modified version called stopifnot_new()
which works in accordance with the man page and
where there are only two additional calls: parent.frame() and eval().
I don't think it can be considered as real performance penalty
as the same or bigger amount of (implicit) evaluations was
already done in the current version:

source("stopifnot_new.R")
stopifnot_new(3 == 5, as.integer(2^32), a <- 12)
Error: 3 == 5 is not TRUE
a
Error: object 'a' not found

Best,
Serguei.


Le 15/05/2017 à 10:39, Martin Maechler a écrit :
Hervé Pagès <hpa...@fredhutch.org>
     on Wed, 3 May 2017 12:08:26 -0700 writes:
     > On 05/03/2017 12:04 PM, Hervé Pagès wrote:
     >> Not sure why the performance penalty of nonstandard evaluation would
     >> be more of a concern here than for something like switch().

     > which is actually a primitive. So it seems that there is at least
     > another way to go than 'dots <- match.call(expand.dots=FALSE)$...'

     > Thanks, H.

     >>
     >> If that can't/won't be fixed, what about fixing the man page so it's
     >> in sync with the current behavior?
     >>
     >> Thanks, H.

Being back from vacations,...
I agree that something should be done here, if not to the code than at
least to the man page.

For now, I'd like to look a bit longer into a possible change to the function.
Peter mentioned a NSE way to fix the problem and you mentioned switch().

Originally, stopifnot() was only a few lines of code and meant to be
"self-explaining" by just reading its definition, and I really would like
to not walk too much away from that original idea.
How did you (Herve) think to use  switch()  here?



     >> On 05/03/2017 02:26 AM, peter dalgaard wrote:
     >>> The first line of stopifnot is
     >>>
     >>> n <- length(ll <- list(...))
     >>>
     >>> which takes ALL arguments and forms a list of them. This implies
     >>> evaluation, so explains the effect that you see.
     >>>
     >>> To do it differently, you would have to do something like
     >>>
     >>> dots <- match.call(expand.dots=FALSE)$...
     >>>
     >>> and then explicitly evaluate each argument in turn in the caller
     >>> frame. This amount of nonstandard evaluation sounds like it would
     >>> incur a performance penalty, which could be undesirable.
     >>>
     >>> If you want to enforce the order of evaluation, there is always
     >>>
     >>> stopifnot(A) stopifnot(B)
     >>>
     >>> -pd
     >>>
     >>>> On 3 May 2017, at 02:50 , Hervé Pagès <hpa...@fredhutch.org>
     >>>> wrote:
     >>>>
     >>>> Hi,
     >>>>
     >>>> It's surprising that stopifnot() keeps evaluating its arguments
     >>>> after it reaches the first one that is not TRUE:
     >>>>
     >>>> > stopifnot(3 == 5, as.integer(2^32), a <- 12) Error: 3 == 5 is
     >>>> not TRUE In addition: Warning message: In stopifnot(3 == 5,
     >>>> as.integer(2^32), a <- 12) : NAs introduced by coercion to integer
     >>>> range > a [1] 12
     >>>>
     >>>> The details section in its man page actually suggests that it
     >>>> should stop at the first non-TRUE argument:
     >>>>
     >>>> ‘stopifnot(A, B)’ is conceptually equivalent to
     >>>>
     >>>> { if(any(is.na(A)) || !all(A)) stop(...); if(any(is.na(B)) ||
     >>>> !all(B)) stop(...) }
     >>>>
     >>>> Best, H.
     >>>>
     >>>> --
     >>>> Hervé Pagès
     >>>>
     >>>> Program in Computational Biology Division of Public Health
     >>>> Sciences Fred Hutchinson Cancer Research Center 1100 Fairview
     >>>> Ave. N, M1-B514 P.O. Box 19024 Seattle, WA 98109-1024
     >>>>
     >>>> E-mail: hpa...@fredhutch.org Phone: (206) 667-5791 Fax: (206)
     >>>> 667-1319
     >>>>
     >>>> ______________________________________________
     >>>> R-devel@r-project.org mailing list
>>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel&d=DwIFaQ&c=eRAMFD45gAfqt84VtBcfhQ&r=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA&m=JwgKhKD2k-9Kedeh6pqu-A8x6UEV0INrcxcSGVGo3Tg&s=f7IKJIhpRNJMC3rZAkuI6-MTdL3GAKSV2wK0boFN5HY&e=
     >>>>
     >>>
     >>

     > -- Hervé Pagès

     > Program in Computational Biology Division of Public Health Sciences
     > Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N,
     > M1-B514 P.O. Box 19024 Seattle, WA 98109-1024

     > E-mail: hpa...@fredhutch.org Phone: (206) 667-5791 Fax: (206)
     > 667-1319

     > ______________________________________________
     > R-devel@r-project.org mailing list
     > https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to