SetGeneric and formula interfaces

John Chambers jmc@research.bell-labs.com
Tue, 02 Jul 2002 08:42:21 -0400


Torsten Hothorn wrote:
> 
> Hi,
> 
> while playing with the `methods' package I was not able to find what the
> recommended way of dealing with the following problem is.
> 
> Suppose there is a generic function `foo' and two functions `foo.default'
> and `foo.formula', in the classical way:
> 
> foo <- function(y, ...) UseMethod("foo")
> 
> foo.default <- function(y, ...) {}
> 
> foo.formula <- function(formula, data, subset, na.action, ...) {
>  ...
>  do.call("foo", y=something appropriate,...)
> }
> 
> If I recall it correctly, foo.formula is the only function that is allowed
> to have different arguments than the generic function has (at least by R
> CMD check).
> 
> Now, using `setGeneric' and `setMethod':
> 
> R> library(methods)
> R>
> R> setGeneric("foo", function(y, ...) standardGeneric("foo"))
> [1] "foo"
> R>
> R> setMethod("foo", signature(y="numeric"),
> + function(y, ...) print("foo with numeric"))
> [1] "foo"
> R>
> R> setMethod("foo", signature(y="formula"),
> + function(y, ...) print("foo with formula"))
> [1] "foo"
> R>
> R> foo(x ~ a)
> [1] "foo with formula"
> R> foo(1:10)
> [1] "foo with numeric"
> 
> fine. But is it possible to have a method that has an argument `formula'
> instead of `y', at least for the sake of compatibility with the classical
> way?

No.

This is one major difference in the "model" for method dispatch from the
"white book" methods.  The old-style methods are defined to re-match the
arguments to the generic before calling the method.

The formal methods are dispatched by evaluating the _body_ of the method
in the frame of the call to the generic, without rematching arguments.

Aside from potential efficiency, the rationale is that the generic
defines the "meaning" or intention of the function, and the methods are,
literally, different methods to implement that intention.

There's nothing very deep here:  obviously you can say
  setMethod("foo", "formula", function(y, ...)foo.formula(y, ...))

We could even re-define the API so that setMethod did roughly the
equivalent automatically, but on the whole the potential for confusion
seems to outweigh the convenience.

> 
> Torsten
> 
> -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
> r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
> Send "info", "help", or "[un]subscribe"
> (in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
> _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._

-- 
John M. Chambers                  jmc@bell-labs.com
Bell Labs, Lucent Technologies    office: (908)582-2681
700 Mountain Avenue, Room 2C-282  fax:    (908)582-3340
Murray Hill, NJ  07974            web: http://www.cs.bell-labs.com/~jmc
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._