[Rd] Questions about S4 style methods and generics

John Chambers jmc@research.bell-labs.com
Thu, 09 May 2002 15:26:02 -0400


Saikat DebRoy wrote:
> 
> >>>>> "John" == John Chambers <jmc@research.bell-labs.com> writes:
> 
>   John> Saikat DebRoy wrote:
>   >>
>   >> I have some questions about S4 style methods and generics.
>   >>
>   >> First of all, is there any way of using default values for arguments
>   >> in the generics/methods? My own experiments show that such arguments
>   >> are always ignored.
> 
>   John> Yes there is and no they are not.
> 
>   John> But there are a couple of points to keep in mind.
> 
>   John> The definition of method dispatch is that the _body_ of the selected
>   John> method is evaluated, without rematching arguments.  That means that it's
>   John> the default values in the (generic) function definition that will be
>   John> found in the context of the call.
> 
> I was in a situation where there is no default method.
> 
> > setGeneric("foo", function(x, y=0) standardGeneric("foo"))
> [1] "foo"
> > setMethod("foo", signature(x="numeric", y="numeric"), function(x, y) x+y)
> [1] "foo"
> > foo(1, 2)
> [1] 3
> > foo(1)
> Error in foo(1) : No direct or inherited method for function "foo" for this call
> 
> So are the default values are substituted in the function call after the
> method signature is matched? 

Hmmm, well "substituted" may not be the best term to use.

What happens here is pretty much determined by the API, not R-specific. 
Your question about defaults has come up before; should be in a
to-be-written FAQ.

Basically everything is standard S (R or S-Plus) up to the point that
standardGeneric is called.  With an ordinary generic function, arguments
are matched but not evaluated, because of lazy evaluation.

Now the dispatch code examines as many arguments as are involved in
existing signatures (2 in your example).  The class for each argument
inserted into the current signature for dispatch is:
  - "missing" if the corresponding argument is missing from the call;
  - the class of the evaluated actual argument otherwise.
Because of the first step, default expressions are not evaluated during
method selection; they obey the standard S rules of lazy evaluation, as
do arguments not needed for the signature.

(Not relevant to the question, but the dispatch is done first in C; if
there is no method matching the signature exactly, then S language code
is used to select a method by inheritance, and the selected method is
cached under the current signature.)

Your later example seems to be a bug of some sort, but I'll examine it
more closely.  Thanks.  (Dispatch on 3+ arguments probably hasn't had
much exercise!)

John
-- 
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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._