 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().

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().

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


Peter Ruckdeschel wrote:

>Hi Seth ,
>
>thank you for your reply.
>
>Seth Falcon  <sfalcon@fhcrc.org> writes:
>
>  
>
>>Peter Ruckdeschel <Peter.Ruckdeschel@uni-bayreuth.de> writes:
>> 
>>
>>    
>>
>>>## now: B00 mother class to B01 and B02, and again B02 "contains" B01 by
>>>setIs:
>>>setClass("B00", representation(a="numeric"))
>>>setClass("B01", representation(a="numeric",b="numeric"), contains= "B00")
>>>setClass("B02", representation(a="numeric",d="numeric"), contains= "B00")
>>>setIs("B02","B01",coerce=function(obj){new("B01", a=obj@a, b=obj@d)},
>>>       replace=function(obj,value){new("B01", a=value@a, b=value@b)})
>>>
>>># now two "+" methods  for B00 and B01
>>>setMethod("+", signature=c("B00","B00"), function(e1,e2){e1@a+e2@a})
>>>setMethod("+", signature=c("B01","B01"), function(e1,e2){e1@b+e2@b})
>>>
>>>x1=new("B02", a=1, d=2)
>>>x2=new("B02", a=1, d=3)
>>>
>>>x1+x2 ## 2 --- why?
>>>   
>>>
>>>      
>>>
>>My impression from reading over the man page for setIs, is that it
>>isn't intended to be used to override the existing inheritance
>>hierarchy.  It also mentions that the return value is the extension
>>info as a list, so that could also be useful in understanding what
>>setIs is doing.  Here's the output for your example:
>>
>>   Slots:
>>                         
>>   Name:        a       d
>>   Class: numeric numeric
>>   
>>   Extends: 
>>   Class "B00", directly
>>   Class "B01", directly, with explicit coerce
>>
>>Use the contains arg of setClass to define the superclasses.  With the
>>contains arg, the order determines the precedence for method lookup.
>>But I suspect you know that already.  
>> 
>>
>>    
>>
>Yes, I have been aware of this, thank you.
>
>  
>
>>>Is there a possibility to force usage of the B01 method /without/
>>>explicitely coercing x1,x2 to B01, i.e. interfere in the dispatching 
>>>precedence, telling R somehow  (by particular arguments for setIs ?)  
>>>to always use the is-relation defined by setIs first before mounting 
>>>the hierarchy tree?
>>>   
>>>
>>>      
>>>
>>Perhaps explaining a bit more about what you are trying to accomplish
>>will allow someone to provide a more helpful suggestion than mine :-)
>>    
>>
>
>In the "real" context, B00 stands for a class "AbscontDistribution",
>which implements absolutely continuous (a.c.) distributions. B01 is
>class "Gammad" which implements Gamma distributions, and B02 is
>class "Exp" which implements exponential distributions. The method
>still is "+", but interpreted as convolution.
>
>For  a.c. distributions, the default method is an FFT-based numerical
>convolution algorithm, while for Gamma distributions (with the same
> scale parameter), analytic, hence much more accurate convolution
>formulas are used. For "Exp", I would tell R that it also 'is' a "Gammad"
>distribution by a call to setIs and use the "Gammad"-method.
>
>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?  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"), ....)

>  
>
>>If you know the inheritance structure you want before run-time, then
>>I'm not seeing why you wouldn't just use the contains arg
>>    
>>
>
>I do not want to use the "+"  method for "B00" for accuracy reasons
>(see above).
>
>The reason why I do not want to implement "B01" ("Gammad")
>as mother class of "B02" is that
>
>(a) the slot structure is not identical --- in the real context Gamma
>and Exp use different parametrizations ---
> + rate for "Exp" (cf ?rexp) and
> + shape for "Gammad" (cf rgamma)
>
>(b) also class "Weibull" could be used as mother class to "Exp",
>and I do not want to decide whether the Weibull or the
>Gamma is the (more) "legitimate" mother to Exp ;-) 
>
>I know: 'contains' could be a vector of classes ---
>c("Gammad", "Weibull")  --- but then which would be
>the  correct slot structure for "Exp" the one of "Gammad"
>or the one of "Weibull" ?
>My context is a bad example, "Gammad", "Weibull"
>do have the same slots, but more generally this /is/ an issue...
> 
>--- So my guess was to rather implement two 'is'-relations
>( "Exp" 'is' "Gammad"  and  "Exp" 'is' "Weibull")
>declared by 'setIs' , and then on run time let the
>dispatching mechanism decide whether to use
>a Gamma or a Weibull method.
>
>But maybe there is a better solution ?
>Any suggestions are welcome.
>
>  
>
>>And if you want to force certain behavior at run-time, then I don't
>>see what's wrong with an explicit coercion using as(foo, "bar").
>>    
>>
>
>If you have two objects E1, E2 of class "Exp" (with the same rate)
>you (or the user for whom we provide these classes)  rather want to
>call "+" by     E1 + E2      than
>by      as(E1, "Gammad") + as(E2,"Gammad")
>...
>
>Anyway, thank you for your help
>
>Peter
>
>______________________________________________
>R-devel@r-project.org mailing list
>https://stat.ethz.ch/mailman/listinfo/r-devel
>
>  
>

	[[alternative HTML version deleted]]

