[Rd] Overloading methods in R

Henrik Bengtsson hb at maths.lth.se
Thu Apr 21 14:46:06 CEST 2005


> -----Original Message-----
> From: r-devel-bounces at stat.math.ethz.ch 
> [mailto:r-devel-bounces at stat.math.ethz.ch] On Behalf Of Ali -
> Sent: Thursday, April 21, 2005 1:28 PM
> To: hb at maths.lth.se
> Cc: r-devel at stat.math.ethz.ch
> Subject: RE: [Rd] Overloading methods in R
> 
> 
> Henrik,
> 
> Thanks for a reply as the author of the package. I understand 
> that you 
> people are interested in discussing this COOP-FOOP fight, 
> however, the 
> original question of this thread is all forgotton. So, I declare the 
> question again:
> 
> -> How to overload methods in classes created by R.oo package? <-
> 
> I even sent you this question by the email provided in the 
> package, but still no answer!

[That one got stuck in my spam filter; I've sent you a reply just before
seing this one. I'll paste thát answer here too, if someone else is interest
or can add to the topic.]

Unfortunately, there is no immediate solution to this in the R language;
neither in S3 nor S4. The problem as is basically that you can only have one
generic function and that all methods dispatch by this generic function are
required to have the same arguments. I've been trying to get a discussion on
this problem, because I see the problem of two people creating two
independent package containing generic functions of the same name but
different arguments - that won't work today (at least not well). [namespaces
help a bit, though]

However, in S3 you can create a "generic" generic function by not specifying
arguments but only '...' - this way any methods can take any arguments (and
you don't force your argument names onto other developer's). Example:

foo <- function(...) UseMethodS3("foo")

foo.ClassA <- function(object, ...) { <code> }
foo.ClassB <- function(x, y, ...) { <code> }

and so on. This will *not* solve your problem of have overloaded methods in
the same class [using COOP thinking]. That is not possible to do, what I
understand. The only way I can think of is to have an ad hoc method which in
turn checks the arguments and dispatch on them. 

foo.ClassA <- function(...) {
  args <- list(...);
  # Investigate names(args) and lapply(args, FUN=class) for further
dispatching
  # to "private" methods .foo_x.ClassA(...), .foo_x_y.ClassA(...). 
}

(This is inline with what Gabor Grothendieck outlined.) However, I am not
sure if the further methods dispatching with NextMethod() will work. You
probably want to define generic functions for .foo_x() and .foo_x_y() so
they in turn can be overloaded by subclasses.

If you figure a good schema for the above, maybe it can be made automatic so
that one can have a

setOverloadMethodS3("foo", "ClassA", function(object, ...) { <code> })
setOverloadMethodS3("foo", "ClassA", function(x, y, ...) { <code> })

to do the above. That would require some inspection of the arguments, but
that is not hard using formals().

So, the above is just a sketch that might or might not work. I think you
best shot is indeed to use S3, because it is a bit more flexible; S4 is
probably too rigid for this purpose.

BTW, I think it would be nice if you can develope an easy way to define
wrappers for C++ and other similar language! [Just don't reinvent the
wheel.]
 
> I am trying to wrap some C++ class into R, so, in the way that you 
> described, I am trying to wrap some COOP 'things' by some 
> FOOP 'things'. 
> Although there are some packages in R that already wrapped 
> some C++ classes 
> into R, none of them kept the originality of the wrapped 
> classes. That is, 
> the original C++ classes are customised and dissolved to R 
> functions. There 
> is nothing wrong with doing this, but, I am wrapping a few 
> hundered C++ 
> classes automatically and apparently it is not possible to 
> customise each of 
> them.
> 
> The good thing about R.oo is that it is a trouble-less 
> interface between 
> COOP and FOOP. In fact, I have already used the package 
> successfully to 
> generate S3 classes from C++ *automatically*. The only big 
> issue that I have 
> with it is that R.oo overwrites overloaded methods and, to keep the 
> originality of the C++ class and bein nice to the end user, I 
> don't want to 
> change the name of the overloaded functions. Also there is 
> this point that 
> sometime in feature S3 classes will become completely 
> obsolete and new 
> packages shouldn't be based on it. So it would be nice to 
> have a 'S4-R.oo'.

I certainly hope S3 will not be obsolete on day and if it is every planned I
certainly would to see a real and sensible open discussion on this long
before being done! [You already know my standpoint here; S3 and S4
complement, not fight, each other]

> Finally, I remind the package author about the original question:
> 
> - How to overload methods in classes created by R.oo package?

So answered aboved.

> with one more question that I add it right now:
> 
> - Why R.00 is not upgraded to S4?

Indeed, I know that Nathan Whitehouse worked on this, see
http://maths.newcastle.edu.au/~rking/R/devel/03b/0584.html. I do not know
the current status of it, but I think he wrote some "white papers" on the
topic. I don't know where and how many they are. There might be something in
the http://www.rho-project.org project.
 
Best wishes

Henrik

> and I hope we have some 'answer'.
> 
> 
> -Ali
> 
> 
> >Hi. Some clarification on R.oo:
> >
> > > -----Original Message-----
> > > From: r-devel-bounces at stat.math.ethz.ch 
> > > [mailto:r-devel-bounces at stat.math.ethz.ch] On Behalf Of 
> A.J. Rossini
> > > Sent: Wednesday, April 20, 2005 6:21 PM
> > > To: Ali -
> > > Cc: r-devel at stat.math.ethz.ch
> > > Subject: Re: [Rd] Overloading methods in R
> > >
> > >
> > > R.oo tries to implement an old-fashioned OO system as 
> found in Java, 
> > > Python, C++, etc.  R's S4 methods implement a nice modern system 
> > > based on the generic function approach , dispatch on argument 
> > > signatures, which is different.
> >
> >I would call them different, rather than old and modern - 
> each kind has 
> >its own use.
> >
> >To the details:
> >It is the Object class that is related to Java & co; the 
> setMethodS3() 
> >and
> >setConstructorS3() methods are orthogonal and just 
> userfriendly wrappers to
> >creating functions manually.
> >
> >The main purpose of Object is provide *reference variables*, 
> with the 
> >main purpose to save memory! This is done by utilizing environment, 
> >which is standard R code, no ugly hacks are used. The Object class 
> >defines operators "$" and "$<-" (and a few others) to access 
> variables 
> >within the environment, which is unique to each instance of class 
> >Object. Indeed, there was a similar feature added in R 
> v1.9.0 (or was 
> >it v2.0.0) to the environment variable; "$" and "$<-" wraps up get() 
> >and assign() methods for easy use. For an object Object, the 
> >environment is in a list structure, contrary to being an environment 
> >directly. The reason for this is that attr(), save() and load() on 
> >environments does (did?) not work as you would expect, cf. 
> >https://stat.ethz.ch/pipermail/r-devel/2002-October/025197.html.
> >
> >The the Object class defines some other methods to simplify 
> life, and 
> >yes, to imitate Java in the sense that it is convenient to 
> inherit from 
> >one single root Class. It does not allow multiple 
> inheritance (although 
> >you can update the class attributes yourself if you wish too).
> >
> >To differ between OOP in Java and S4/Dylan, I prefer to refer to the 
> >former as class-object-oriented programming (COOP) and the latter as
> >function-object-oriented programming (FOOP). Then, comparing 
> COOP style 
> >with
> >FOOP style is a bit like comparing peas to apples. I would say that 
> >choosing
> >COOP or FOOP is a design issue that has to do what you are trying to
> >implement and not a
> >once-in-a-lifetime/I-want-to-belong-to-this-group-of-people 
> decision. For
> >what I am working on, I found that higher level 
> implementation, where it is
> >clear that a method "belongs" to a class, is easier using 
> COOP. Classes for
> >statistical and mathematical modelling, where functions does 
> not belong to 
> >a
> >specific object, is probably better i FOOP. So, please do 
> not rule out one
> >for the other!
> >
> >The setMethodS3() is a wrapper to automatically test for generic and
> >default
> >functions and create generic functions when needed etc. So
> >
> >setMethodS3("foo", "MyClass", function(object, ...) {
> >   #something
> >})
> >
> >replaces things like
> >
> >if (exists("foo.MyClass", mode="function"))
> >   warning/stop("Replacing foo.MyClass")
> >
> >if (exists("foo", mode="function") && !"not a generic function")
> >   try to rename foo() to foo.default(), but only if foo.default()
> >   does not already exists.
> >
> >... and so on until you can safely write
> >
> >foo.MyClass <- function(object, ...) {
> >   # something
> >}
> >
> >setConstructorS3() is basically like the above, but it does 
> not create 
> >a generic function nor a class specific method, but a 
> "plain" function
> >
> >setConstructorS3("MyClass", function(args, ...) {
> >   # Something
> >}
> >
> >to get
> >
> >MyClass <- function(args, ...) {
> >   # Something
> >}
> >
> >with check for naming conflicts etc.
> >
> >Cheers
> >
> >Henrik Bengtsson
> >(author of R.oo)
> >
> > > While the R documentation for S4 classes is quite useful 
> (spanning 
> > > the green book, the BioC developer help pages, V&R's book on 
> > > programming, and some other papers), I've found that for a nice 
> > > background, Paul Graham's ANSI Lisp book, and in particular the 
> > > nicely written chapter on CLOS, provides a nice 
> introduction to the 
> > > thought process.
> > >
> > > With respect to the R.oo package, the author might be the best 
> > > source for that.
> > >
> > > Another package which you might take a look at is the 
> proto package, 
> > > which provides prototype object-orientation similar to 
> that found in 
> > > XLispStat, and also might help with what you are trying to do.
> > > However, I suspect that learning about the S4 system will
> > > provide more benefit in the future.
> > >
> > > best,
> > > -tony
> > >
> > > On 4/20/05, Ali - <saveez at hotmail.com> wrote:
> > > > Sean,
> > > >
> > > > Thanks, but, I am actually talking about overloading
> > > 'methods' and not
> > > > 'functions', or you may want to answer this question: How
> > > to overload
> > > > methods in classes created by R.oo package?
> > > >
> > > > >
> > > > >On Apr 20, 2005, at 8:16 AM, Ali - wrote:
> > > > >
> > > > >>(1) It seems to me that, generally, in R it is not 
> possible to 
> > > > >>overload functions. Is that right?
> > > > >>
> > > > >>(2) Assuming that the above is true, or partially true,
> > > is there any
> > > > >>extra packages to handle overloading in R?
> > > > >>
> > > > >>(3) Assuming (1) is TRUE and (2) is FALSE, can anyone
> > > provide some
> > > > >>advice on developing some function that understand what the 
> > > > >>arguments  are and then calls the right overloaded function?
> > > > >>
> > > > >>It would be something like this:
> > > > >>
> > > > >>overloadedFunction1 <- function(x) {};
> > > > >>
> > > > >>overloadedFunction2 <- function(x, y) {};
> > > > >>
> > > > >>theFunction <- function(...)
> > > > >>{
> > > > >>   # How to identify ... and call the right 
> overloaded function? 
> > > > >>}
> > > > >>
> > > > >
> > > > >Ali,
> > > > >
> > > > >You are probably interested in "methods".  Functions can
> > > have different
> > > > >"methods" depending on what the arguments and their types
> > > are.  A first
> > > > >place to look is:
> > > > >
> > > >
> > > 
> >http://cran.r-project.org/doc/manuals/R-exts.html#Generic-functions
> > > >-
> > > > >and-methods
> > > > >
> > > > >Sean
> > > > >
> > > >
> > > > ______________________________________________
> > > > R-devel at stat.math.ethz.ch mailing list 
> > > > https://stat.ethz.ch/mailman/listinfo/r-devel
> > > >
> > >
> > >
> > > --
> > > best,
> > > -tony
> > >
> > > "Commit early,commit often, and commit in a repository 
> from which we 
> > > can easily roll-back your mistakes" (AJR, 4Jan05).
> > >
> > > A.J. Rossini
> > > blindglobe at gmail.com
> > >
> > > ______________________________________________
> > > R-devel at stat.math.ethz.ch mailing list 
> > > https://stat.ethz.ch/mailman/listinfo/r-devel
> > >
> > >
> >
> 
> ______________________________________________
> R-devel at stat.math.ethz.ch mailing list 
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 
>



More information about the R-devel mailing list