Re: [Rd] S4 methods semantics questions
On Mar 25, 2005, at 7:26 AM, John Chambers wrote: 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 ;-) True enough. Though I suppose you could have done something with arguments that are method calls by inspecting valueClass to at least limit the set of possible types. :-) 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 Ah, interesting. I can't decide if thats a feature or a bug either :-) --- Byron Ellis ([EMAIL PROTECTED]) "Oook" -- The Librarian __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel --- Byron Ellis ([EMAIL PROTECTED]) "Oook" -- The Librarian __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] S4 methods semantics questions
John Chambers <[EMAIL PROTECTED]> writes: > 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 FWIW, I've encountered the same error that the OP described. I certainly don't know if it is a bug, but I can say that I expected it to work based on the documentation of setMethod. I ended up with a different workaround: if you don't need to do dispatching on the default arguments, you can set setGeneric("foo", function(x, ...) standardGeneric("foo")) and then methods with defaults defined in their function do the expected thing. Best, + seth __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] S4 methods semantics questions
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 ([EMAIL PROTECTED]) "Oook" -- The Librarian __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] S4 methods semantics questions
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. 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. 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 --- Byron Ellis ([EMAIL PROTECTED]) "Oook" -- The Librarian __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel