[Rd] codetools wrongly complains about lazy evaluation in S4 methods

Martin Maechler m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Wed Jun 21 12:11:42 CEST 2023


>>>>> Martin Maechler 
>>>>>     on Fri, 16 Jun 2023 11:41:12 +0200 writes:

>>>>> Mikael Jagan 
>>>>>     on Thu, 15 Jun 2023 22:00:45 -0400 writes:

    >> On 2023-06-15 5:25 pm, Hervé Pagès wrote:
    >>> Oh but I see now that you've already tried this in your
    >>> R/AllGenerics.R, sorry for missing that,

    > yes, this one:

>   setGeneric("qr.X",
> 	     function(qr, complete = FALSE, ncol, ...)
> 		 standardGeneric("qr.X"),
> 	     useAsDefault = function(qr, complete = FALSE, ncol, ...) {
> 		 if(missing(ncol))
> 		     base::qr.X(qr, complete = complete)
> 		 else base::qr.X(qr, complete = complete, ncol = ncol)
> 	     },
> 	     signature = "qr")
> 
> where the 'signature = "qr"' is perfect (and as Hervé suggests).
> 
> but the complication in useAsDefault = ..  is really a bit ugly
> ... notably if one compares with the nice original  base :: qr.X ()

In spite of the "ugliness" (above) and of the "conflict
rules"-resolution I've talked about below,
I've now committed the above + implicit generic definition to
R-devel's {methods} package.

After all, it provides a clean situation also for other S4-using
developers.

I'm still musing if this is a bug fix to be back ported to the
R-4-3-branch eventually.

Best,
Martin

>     >> but that you worry about the following message being 
>     >> disruptive on CRAN:
>     >> 
>     >>     The following object is masked from 'package:base':
>     >> 
>     >>         qr.X
>     >> 
>     >> Why would that be? As long as you only define methods for
>     >> objects that **you** control everything is fine. In other
>     >> words you're not allowed to define a method for "qr"
>     >> objects because that method would override
>     >> base::qr.X(). But the generic itself and the method that
>     >> you define for your objects don't override anything so
>     >> should not disrupt anything.
> 
>     > Yes, maybe it would be fine in principle, and of course
>     > many popular packages emit startup messages.  Still, in
>     > practice, I think that people are quite accustomed to
>     > library(Matrix) being "silent", and probably a nontrivial
>     > fraction of our reverse dependencies would encounter new
>     > NOTEs about differences between *.Rout and *.Rout.save,
>     > etc.
> 
> I tend to agree with Hervé that the  "masked" warning here is
> a false positive.
> 
> I also agree with Mikael  that we would not want this for every
> default use of   library(Matrix)
> 
> I believe we should fix it by using conflictRules(), and from
> reading ?conflictRules I understand we could do that by setting
> 
>   options(conflict.policy = list(mask.ok = "qr.X"))
> 
> possibly even in Matrix package's load or attach hook
> [[and if really really necessary even as hack inside library()'s checks]]
> 
>     > The fraction of users who will ever call this method for
>     > qr.X is very very small compared to the fraction who will
>     > be confused or annoyed by the message.  Hence my hope that
>     > an implicit generic qr.X could become part of package
>     > methods, notably as an implicit generic qr.R already lives
>     > there ...
> 
>     > Or maybe there is a way for Matrix to define qr.X as an
>     > implicit generic without creating other problems, but my
>     > experiments with setGenericImplicit were not promising ...
> 
> In principle, I'd say that setGenericImplicit() would be a good
> / "the correct" approach,  but as you already tried
> unsuccessfully, I'm not claiming the principle.
> 
> Martin
> 
> 
>     > Mikael
> 
>     >> H.



More information about the R-devel mailing list