[Rd] setIs and method dispatch in S4 classes

Peter Ruckdeschel Peter.Ruckdeschel at uni-bayreuth.de
Mon Apr 10 21:22:01 CEST 2006


Hi Seth and John,

Thank you for your helpful responses,

>John Chambers <jmc at r-project.org> writes:
>>From your description of the application, it sounds like you would be
>>better off just forcing "+" to behave as you want.  Using inheritance is
>>a much more powerful mechanism & can introduce results you don't want,
>>as it seems to have in this case.
>>
>>An important point about using inheritance is that the subclass is a
>>asserted to be substitutable for the superclass for ALL purposes.  This
>>applies whether using "contains=" or  setIs().

I am not sure whether I got the meaning of "substitutable for the
superclass for ALL purposes" :

In the application I sketched, any  Exp(rate = lambda) distribution
really /is/ a Gammad(shape = 1, scale = 1/lambda) distribution; 
so my understanding is that "Exp" is substitutable for "Gammad"
for ALL purposes.

"Gammad" was not designed to be the motherclass to "Exp" right
from the beginning because the same 'is'-relation also applies to
"Weibull": any Exp(rate = lambda) distribution /is/ a
Weibull(shape = 1, scale = 1/lambda) distribution.

Does "substitutable for the superclass for ALL purposes"
mean 'without ambiguity' (as might enter through Weibull/Gammad)?

>>When the focus is on a particular function, it's usually better to
>>implement methods for that function, maybe along with setAs()
>>methods--not setIs().

You mean I should not leave the coercion decision up to the dispatching
mechanism?

>>It seems likely that such a solution would be cleaner in design, not to
>>mention that it would likely work.  (see also suggestion below)

Yes, your indication does work; thank you!
 
>>Peter Ruckdeschel <peter.ruckdeschel at uni-bayreuth.de> writes:
>>>Of course, I could also declare explicitly "+" methods for signatures
>>>c("Exp", "Exp"), c("Exp", "Gammad"), and c("Gammad", "Exp") in
>>>which I would then use as(.) to coerce "Exp" to "Gammad"
>>> (and again the same procedure for further Gamma-methods).
>>>
>>>But, this would create an extra (3 or possibly much more) methods
>>>to dispatch, and I doubt whether this really is the preferred
>>>solution.
>>>
>> Why not?

It simply did not seem to me elegant to have three calls to
setMethod() doing more or less the same thing.
I thought that, as elegant as R solutions from the R core are
most times, there should be some mechanism to avoid this
threefold code---and in fact you indicated how to---
thank you!

>> And you can avoid some of the extra methods by defining a
>> virtual class that is the union of the classes for which you
>> want the new methods.
>>
>> Something like (untested code!)
>>
>> setClassUnion("analyticConvolution", c("Exp", "Gammad"))
>> setMethod("+", c("analyticConvolution", "analyticConvolution"),
>> ....)

Seth Falcon <sfalcon at fhcrc.org> writes:
> Why class union here and not an abstract superclass?

Am I right: the class generated by setClassUnion() does not
enter the inheritance tree / mechanism?

setClassUnion()---at least in my case---solves the problem;
thank you again.

[snip]

Peter



More information about the R-devel mailing list