[R] questions about setMethod("Arith", ...)

John Chambers jmc at research.bell-labs.com
Thu Jul 8 22:18:05 CEST 2004


The version of "distr" on CRAN at the time of this posting is seriously
broken, in ways that are not directly related to Arith or to group
generics in general, but which are enough to explain the problems you
report (and much else besides).

You include a NAMESPACE file with this package.  If you really want to
use namespaces (somewhat questionable in this case), you must include
exportMethods() directives for all functions in setMethod() calls.  You
have not done so, therefore in principle all your methods are private,
except those for generic functions exported from distr itself.

(Because of the way primitive functions currently dispatch methods, you
probably didn't see as much evidence as you should have showing the
error.  If you had used the  showMethods() function recommended in
"Programming with Data" to view methods, not the getMethods() function,
you would have seen that distr created no public methods for "/" or the
other arithmetic operators.)

The distr package has a couple of other obvious questionable features. 
It takes a very long time for library(distr) to be executed.  For
packages with substantial class and method definitions, the
traditionally installed R package is slow to attach, because R does all
the computations in the package source each time the library is
attached.  You should use the -s option to INSTALL to create a saved
image.  Also, package distr overrides the objects F and T in the base
package, which is likely to cause problems for many users, especially
those coming from S-Plus.

Your other comments below mostly come from not recognizing that methods
for a specific member of the group ("/", "+") always take precedence
over any methods for the group generic.

It's very desirable that reports to r-help  (especially those implying a
bug) be based on clear, self-contained examples using reliable packages
only.  Otherwise anyone trying to respond has to search through your
code trying to find out what's going on, which will make a response to
any further postings less likely.  This posting is an example.

Sorry to be severe.  Your package looks interesting--do persevere with
it, but you should test future versions more thoroughly before
submitting them to CRAN.

John Chambers


Matthias Kohl wrote:
> 
> Hi,
> 
> we have some questions concerning the definition of new arithmetic methods.
> 
> In our package "distr" (on CRAN) we define some new arithmetic methods
> for "+", "-", "*", "/".
> After loading "distr" the corresponding arithmetic methods work. Now, if
> we define a new
> class and also a new method for one of the arithmetic methods "+", "-",
> "*", "/", still everything works fine. But, if we then define new
> methods for the whole group "Arith", the arithmetic methods of "distr"
> no longer work. (for more details see example code below)
> What are we missing?
> 
> Moreover, there is a certain precendence; i.e., if one defines a single
> arithmetic method (e.g., "/") and alterwards defines a method for the
> whole group "Arith", the "old" method "/" remains valid.
> However, if we first define a method for the whole group "Arith" and
> afterwards define a new single arithmetic method (e.g., "+") the new one
> is valid. (for more details see example code below).
> Is this intended?
> 
> Thanks for your help,
> Matthias, Thomas
> 
> ###########################################################
> ## Example code
> ###########################################################
> require(distr)
> getMethods("/")  # shows the corresponding methods of "distr"
> 
> ## now define a new class "track" (see Chambers (1998))
> ## and define "/"
> 
> setClass("track", representation(x = "numeric", y = "numeric"))
> setMethod("/", signature("track", "numeric"),
>           function(e1, e2){ e1 at y = e1 at y/e2; e1 })
> 
> getMethods("/")  # shows the corresponding methods
>                  # of "distr" and class "track"
> 
> (N <- Norm()) # creates an object of standard normal distribution
> (N1 <- N/3) # works
> (tr <- new("track", x = 1:3, y = 4:6))
> (tr1 <- tr/3) # works
> 
> ## now define new methods for "Arith"
> setMethod("Arith", signature("track", "numeric"),
>           function(e1, e2){
>             e1 at x = callGeneric(e1 at x, e2)
>             e1
>           })
> 
> getMethods("/") # "/" for "distr" is lost
> N2 <- N/3 # fails
> (tr2 <- tr/3) # works, "but" still the "old" method
> tr + 2 # works
> 
> ## now a new method "+"
> setMethod("+", signature("track", "numeric"),
>           function(e1, e2){ e1 at y = e1 at y+e2; e1 })
> 
> tr + 2 # works, "but" with the "new" method
> 
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://www.stat.math.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html

-- 
John M. Chambers                  jmc at bell-labs.com
Bell Labs, Lucent Technologies    office: (908)582-2681
700 Mountain Avenue, Room 2C-282  fax:    (908)582-3340
Murray Hill, NJ  07974            web: http://www.cs.bell-labs.com/~jmc




More information about the R-help mailing list