From Peter.Ruckdeschel at uni-bayreuth.de  Tue May 23 17:50:30 2006
From: Peter.Ruckdeschel at uni-bayreuth.de (Peter Ruckdeschel)
Date: Tue, 23 May 2006 17:50:30 +0200
Subject: [Rd] confused by inheritance...
Message-ID: <44732F46.7030109@uni-bayreuth.de>

> This may be related to the problems with "greedy" search for inherited 
> methods discussed previously on this list (or may not, it's a bit 
> different).

Thank you very much for your explanation --- at least this is not a silly
fault from our side!

> In any case, the likely fix will be a substantial cleaning up of generic 
> functions hoped for in the next release.
> 
> Meanwhile, "Keep it simple" is the best advice (and a good idea 
> anyway).  If you remove the irrelevant z= part of the signatures, the 
> anomalous result goes away.

Well, as you might have guessed, the z= part is only irrelevant in
the code sniplet I have posted to r-devel as an example...

In our application, 'foo' is an expectation function E() which may be called
as follows:

E(x)          ## returns the expectation of a r.v. X distributed
              ## according to distribution x
E(x,fun)      ## returns the expectation of a r.v. fun(X) where X is distributed
              ## according to distribution x
E(x,cond)     ## returns the expectation of a r.v. X given condition 'cond' is
              ## in force and where X is distributed according to distribution x
E(x,fun,cond) ## returns the expectation of a r.v. fun(X) given condition 'cond' is
              ## in force and where X is distributed according to distribution x

Would you have any suggestion how to organize this in a simpler way than
with signatures

"Distribution", "missing", "missing"
"Distribution", "function", "missing"
"Distribution", "missing", "numeric"
"Distribution", "function", "numeric"

respectively?

--------------------------------------------------------------------------------


> By the way, the getMethod() in your example tells us nothing, 
> since it does not use inheritance.  See its documentation.

Yes, but since 'target' and 'defined' are identical---

Signatures:
        x    y         z
target  "A2" "missing" "missing"
defined "A2" "missing" "missing"

---I would have guessed that the dispatching mechanism would
use this method.

> If you use selectMethod() you see the same result as the method dispatch.

...but this would have made me think that somehow
(perhaps by an unintended call to removeMethod())
during the dispatching mechanism, the registration of  my
("A2","missing","missing")-method would have been deleted.

This is not the case, and could be excluded after
having a look at getMethod() --- so at least for me,
getMethod() did provide some information ...

This idea of a registration being deleted may sound silly to you,
but it was my first guess after the following code (in the setup
of my posted example):

foo(x2)      ## gives 3 as it should
foo(x2,y=2)  ## casts to "A1" and gives (2,2) as it should
foo(x2)      ## now gives 2 as if x2 were permanently cast to "A1"
setMethod("foo",signature(x = "A2", y = "missing", z = "missing"),
   function(x)x at c )
foo(x2)      ## again gives 3 as it should

Thanks again

Peter

---------------------------------------------------------------------------
> Peter Ruckdeschel wrote:
> 
>>Hi r-devels,
>>
>>I am stuck in some S4 inheritance problem:
>>
>>setClass("A",representation(a="numeric"))
>>setClass("A1",representation(b="numeric"),contains="A")
>>setClass("A2",representation(c="numeric"),contains="A1")
>>
>>if(!isGeneric("foo")){
>>    setGeneric("foo", function(x,y,z, ...) standardGeneric("foo"))
>>}
>>
>>setMethod("foo",signature(x = "A", y = "missing", z = "missing"),
>>    function(x)x at a )
>>setMethod("foo",signature(x = "A1", y = "missing", z = "missing"),
>>    function(x)x at b )
>>setMethod("foo",signature(x = "A2", y = "missing", z = "missing"),
>>    function(x)x at c )
>>setMethod("foo",signature(x = "A1", y = "numeric", z = "missing"),
>>    function(x,y)c(x at b,y) )
>>
>>
>>x2 <- new("A2", a=1, b=2, c=3)
>>
>>foo(x2)      ## gives 3 as it should
>>foo(x2,y=2)  ## casts to "A1" and gives (2,2) as it should
>>foo(x2)      ## now gives 2 as if x2 were permanently cast to "A1"
>>## However:
>>x2  ## of class "A2" as it should
>>getMethod("foo",signature(x = "A2", y = "missing", z = "missing"))
>>    ## function(x)x at c
>>
>>### What has happened in the dispatching mechanism between
>>## in the line           foo(x2,y=2)             ?



[Rd] confused by inheritance...
Peter Ruckdeschel