[Rd] S4 methods semantics questions

John Chambers jmc at R-project.org
Fri Mar 25 16:26:07 CET 2005

Byron Ellis wrote:

> Some quick questions about S4 methods.
> Does the typing of S4 methods mean that lazy evaluation is no longer 
> possible? It seems that you would need to evaluate the arguments to 
> determine their type at dispatch.

Yes, it would be a neat trick to know the class of an actual argument 
without evaluating it ;-)

However, the evaluation proceeds stepwise until a unique method matches, 
so that arguments not needed to do the dispatch will not yet be 
evaluated.  The order of evaluation is controlled by the signature of 
the generic, by default all the arguments in order, but specifiable via 
the signature= argument to setGeneric.

> Second, what role, if any, do default arguments play in S4 methods? I 
> notice that you can put default arguments into generics but that the 
> dispatch is still done on the type of the calling argument rather than 
> the default argument, though the default arg is substituted. 

Yes, dispatch depends on the call, not on the default expressions for 
the arguments.  If an actual argument is missing, the dispatch tries to 
match "missing" or "ANY".

> However, 
> default values for arguments in method definition seem to be stripped 
> or, more likely, overridden at dispatch by the calling argument (i.e. 
> "missing").
> Some examples:
> setGeneric("foo",function(x="bar") standardGeneric("foo"))
> setMethod("foo","missing",function(x) print(x))
>  >foo()
> [1] "bar"
> setGeneric("foo",function(x,y) standardGeneric("foo"))
> setMethod("foo","numeric",function(x,y=2) x+y)
>  >foo(1)
> Error in foo(1) : argument "y" is missing, with no default

Well, the intent is that defaults are indeed taken from the method, if 
there is a default there, otherwise from the generic.  It looks as if 
there is a bug in the case that the generic has NO default for that 
argument (unless, of course, it's a subtle feature, but not that I can 
think of at the moment).

Your example works as intended if there is a default expression for y in 
the generic:

R> setGeneric("foo",function(x,y=stop("Need y")) standardGeneric("foo"))
[1] "foo"
R> setMethod("foo","numeric",function(x,y=2) x+y)
[1] "foo"
R> foo(1)
[1] 3

> ---
> Byron Ellis (ellis at stat.harvard.edu)
> "Oook" -- The Librarian
> ______________________________________________
> R-devel at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

More information about the R-devel mailing list