[R] Additional arguments in S3 method produces a warning

Berwin A Turlach berwin at maths.uwa.edu.au
Thu Mar 16 13:37:14 CET 2006


G'day Martin,

>>>>> "MM" == Martin Maechler <maechler at stat.math.ethz.ch> writes:

    MM> [...]
    MM> The grain of truth in Henrik's statement is that for a generic
    MM> function, S3 or S4, one should carefully consider which
    MM> arguments should be shared by all methods and which not.  But
    MM> having at least one `` non-... '' argument should be the rule,
    MM> and is even a necessity for S4.  Hence I'd strongly discourage
    MM> defining generic functions with only a (...) argument list.
I was pondering this question recently too and was already wondering
about sending an e-mail to ask for clarification to r-help or r-devel.

What are the arguments against having only a (...) argument list for
the generic?

I can think of several arguments why using only a (...) argument list
should be o.k.

First, I noticed that there are examples in R base that use this
construct, e.g.:

      > seq
      function (...) 
      UseMethod("seq")
      <environment: namespace:base>

Secondly, if I plan to write several methods for a generic and for
these methods the "canonical" name for the first parameter differ, it
would make sense to me to use only a (...) argument list for the
generic.  As an example from R, take the princomp() command:

      > princomp
      function (x, ...) 
      UseMethod("princomp")
      <environment: namespace:stats>
      > princomp.default
      Error: object "princomp.default" not found
      > getAnywhere("princomp.default")
      [...]
      
      function (x, cor = FALSE, scores = TRUE, covmat = NULL, subset = rep(TRUE, 
          nrow(as.matrix(x))), ...) 
      {
      [...]
      }
      <environment: namespace:stats>
      > getAnywhere("princomp.formula")
      [...]
      
      function (formula, data = NULL, subset, na.action, ...) 
      {
      [...]
      }
      <environment: namespace:stats>

I would argue that it is natural to use "formula" as the first
argument to princomp.formula and "x" as the first argument to
princomp.default.  But as the generic is princomp(x, ...), the
princomp.formula method does not comply with two of the three
recommendations in the chapter on "Generic functions and methods" in
"Writing R Extensions".

Thus, without more information what happens if these recommendations
are not followed, I would hesitate to use such code in my own
packages.  I would either make the generic of princomp have only a
(...) argument, or call the first argument of the princomp.formula
method "x" (which would obfuscate the code of that function a bit).


Lastly, I would suggest if the generic for transform would have been:

      > transform
      function (...) 
      UseMethod("transform")
      <environment: namespace:base>

instead of the current

      > transform
      function (x, ...) 
      UseMethod("transform")
      <environment: namespace:base>

Then a certain R user would not have reported a 10 sec puzzle to
r-devel recently: 
        https://stat.ethz.ch/pipermail/r-devel/2006-February/036492.html
(And I guess for many other R users solving this puzzle would have
taken more than 10 sec.)
And it is hard to see what purpose the argument "x" is actually
serving in argument list of the generic.  So why not use a (...)
argument list?

Thus, what speaks against a (...) argument list for a S3 generic?

Cheers,

        Berwin




More information about the R-help mailing list