[R-pkg-devel] slightly polemic question re R CMD check

Jeff Newmiller jdnewm|| @end|ng |rom dcn@d@v|@@c@@u@
Sun Mar 8 18:22:26 CET 2020


... also, the only reason non-generic functions using ellipsis can throw an error when an argument is not used is that they keep passing ... on to functions that recursively encounter fumctions that eventually do not accept an ellipsis argument. If the function calls a generic with an ellipsis argument then we are back into the generic conundrum again and the user will experience the normal function failing to catch unused arguments.

On March 8, 2020 10:14:49 AM PDT, Jeff Newmiller <jdnewmil using dcn.davis.ca.us> wrote:
>R encourages the use of ... particularly in S3 generics, to avoid
>over-depending on inheritance to enable flexible use of these generics.
>That is, when you call the generic without knowing which class you are
>giving it, you cannot specify class-specific arguments. However, some
>methods have obvious alternative class-specific behaviors that are
>typically enabled using class-specific arguments (e.g. plot). You
>cannot support both fully-generic calls and class-specific calls
>without giving the generic some flexibility that won't get used in some
>cases.
>
>
>On March 8, 2020 9:41:51 AM PDT, David Hugh-Jones
><davidhughjones using gmail.com> wrote:
>>Hi Jeff,
>>
>>I wouldn't say R encourages that in general. Non-generic functions
>will
>>throw an error if you use a non-existent argument. And some generic
>>functions check for it:
>>
>>seq(1, 3, blah = 1)
>>[1] 1 2 3
>>Warning message:
>>In seq.default(1, 3, blah = 1) :
>> extra argument ‘blah’ will be disregarded
>>
>>In fact there is even a `chkDots()` function to help with this -
>which,
>>despite having used R or 17 years, I first discovered today :-). So,
>it
>>seems the R base developers thought lenient argument checking could be
>>a
>>bad thing, presumably because it lets errors go undetected.
>>
>>Maybe chkDots is a reasonable workaround. But I wonder what the
>>rationale
>>is for R CMD check enforcing that methods *must* be as lenient as the
>>generic. It seems to lead to a lot of documentation of the form:
>>
>>@param ... Not used.
>>
>>Cheers,
>>David
>>
>>
>>On Sun, 8 Mar 2020 at 16:24, Jeff Newmiller <jdnewmil using dcn.davis.ca.us>
>>wrote:
>>
>>> You seem to think this is a bad thing. R does encourage lenient
>>argument
>>> checking... what rock have you been under for the last 20 years?
>>>
>>> On March 8, 2020 5:41:51 AM PDT, David Hugh-Jones <
>>> davidhughjones using gmail.com> wrote:
>>> >You're quite right :-) But I think the polemic still holds, because
>>I
>>> >have
>>> >to add manual argument checking to all my methods, which has a cost
>>in
>>> >lines of code. Indeed, few base R methods have chosen to do this.
>In
>>> >effect, the current setup encourages writing methods with "lenient"
>>> >argument specifications.
>>> >
>>> >Thank you for the suggestion about ellipsis.
>>> >
>>> >On Sun, 8 Mar 2020, 11:04 Gábor Csárdi, <csardi.gabor using gmail.com>
>>wrote:
>>> >
>>> >> You can add the ... argument to chop.default(), and then check
>>that
>>> >> length(list(...)) is zero.
>>> >>
>>> >> Also, you might be interested in the ellipsis package.
>>> >>
>>> >> Gabor
>>> >>
>>> >> On Sun, Mar 8, 2020 at 10:56 AM David Hugh-Jones
>>> >> <davidhughjones using gmail.com> wrote:
>>> >> >
>>> >> > Hi all,
>>> >> >
>>> >> > My package defines the following method and generic:
>>> >> >
>>> >> > chop <- function (x, ...) UseMethod("chop")
>>> >> >
>>> >> > chop.default <- function (x, breaks, labels, extend = NULL,
>drop
>>=
>>> >TRUE)
>>> >> {
>>> >> > ... }
>>> >> >
>>> >> > R CMD check then gives a warning:
>>> >> >
>>> >> > W  checking S3 generic/method consistency (695ms)
>>> >> >    chop:
>>> >> >      function(x, ...)
>>> >> >    chop.default:
>>> >> >      function(x, breaks, labels, extend, drop)
>>> >> >
>>> >> >    See section ‘Generic functions and methods’ in the ‘Writing
>R
>>> >> >    Extensions’ manual.
>>> >> >
>>> >> > I can fix this by adding a ... argument to chop.default:
>>> >> >
>>> >> > chop.default <- function (x, breaks, labels, extend = NULL,
>drop
>>=
>>> >> > TRUE, ...)
>>> >> >
>>> >> > But that makes the code less robust because e.g.
>>> >> >
>>> >> > chop(x, Breaks = 1:3)
>>> >> >
>>> >> > will no longer throw an error from the misspelled argument.
>>> >> >
>>> >> > Or I can write:
>>> >> >
>>> >> > chop(x, breaks, labels, extend, drop) UseMethod("chop")
>>> >> >
>>> >> > but this means I cannot use a different interface for a
>>different
>>> >method.
>>> >> >
>>> >> > This seems like a mistake. (That's the polemic.) Or am I
>missing
>>a
>>> >better
>>> >> > way? (That's the question.)
>>> >> >
>>> >> > David
>>> >> >
>>> >> >         [[alternative HTML version deleted]]
>>> >> >
>>> >> > ______________________________________________
>>> >> > R-package-devel using r-project.org mailing list
>>> >> > https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>> >>
>>> >
>>> >       [[alternative HTML version deleted]]
>>> >
>>> >______________________________________________
>>> >R-package-devel using r-project.org mailing list
>>> >https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>>
>>> --
>>> Sent from my phone. Please excuse my brevity.
>>>

-- 
Sent from my phone. Please excuse my brevity.



More information about the R-package-devel mailing list