From ripley at stats.ox.ac.uk  Tue Sep  5 11:49:35 2006
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Tue, 5 Sep 2006 10:49:35 +0100 (BST)
Subject: [Rd] setMethod("Summary")
In-Reply-To: <Pine.LNX.4.64.0609050958480.13577@gannet.stats.ox.ac.uk>
References: <C7B9E5CB-E340-445D-A5B9-FC86AB6CC1DE@soc.soton.ac.uk>
	<C4E5D78B-28AB-4A25-8112-3668F31444E4@mac.com>
	<E28E6E71-5DD8-4B38-81C9-BB6014F6C16E@soc.soton.ac.uk>
	<17661.14016.528539.481357@stat.math.ethz.ch>
	<Pine.LNX.4.64.0609050958480.13577@gannet.stats.ox.ac.uk>
Message-ID: <Pine.LNX.4.64.0609051034220.29103@gannet.stats.ox.ac.uk>

On Tue, 5 Sep 2006, Prof Brian Ripley wrote:

> On Tue, 5 Sep 2006, Martin Maechler wrote:
> 
> > >>>>> "Robin" == Robin Hankin <r.hankin at noc.soton.ac.uk>
> > >>>>>     on Tue, 5 Sep 2006 08:58:23 +0100 writes:
> > 
> >     Robin> Dear Franklin
> >     Robin> thank you for this.
> > 
> > yes, and he *did* send it already last week.
> > 
> >     Robin> Your suggestion works.
> > 
> > and continues to do so in R-devel aka "R-2.4.0 alpha" (as of today?)
> > 
> >     Robin> But now I'm confused because I'm not sure how  
> >     Robin> the
> >     Robin> setGeneric() call actually helps.
> > 
> > Robin, I think you got confused because you are mixing S3 and S4
> > ("max.brob" is S3).
> > 
> > You should (typically) not define S3 methods for S4 classes,
> > and you should definitely not do it in this case where Franklin 
> > has shown the correct S4 way.
> > (and for my taste you should also not do it for the "Logic" case
> >  in that other thread last week: It does not bring you anything and is
> >  ugly for me, from the point of view of S4.)
> 
> But it *does* bring you something, efficiency.  If all you want to do is 
> to stop the default method dispatching, using an S3 method can be lot more 
> efficient than an S4 method.  In the example which has been omitted here, 
> making 'max' S4 generic adds an overhead to *all* calls to max() in the 
> rest of the session.  Adding a max.brob method costs nothing at all (max 
> is already S3 generic and efficiently so).

Another issue.  I meant in the session commands, and forgot to mention 
what happens to calls to max() from within functions.  max() is in the 
base namespace.  If you add an S3 method, it will be used by all functions 
calling max(). If you make the function S4 generic, the S4 generic only 
gets called if your package is ahead of the base namespace in the current 
search(), that is from your own package and from packages without 
namespaces.

Now, the current behaviour is

> setClass("foo", "numeric")
[1] "foo"
> xx <- new("foo", pi)
> setMethod("max", signature="foo", function(x, ..., na.rm=FALSE) 
stop("foo"))
[1] "max"
> max(xx)
Error in max(xx) : foo
> base::max(xx)
[1] 3.141593

(and I got an error and then a segfault after leaving off na.rm=FALSE, 
which ought to be allowed).

> max.foo <- function(...) stop("S3 foo")
> base::max(xx)
Error in max.foo(..., na.rm = na.rm) : S3 foo

That's probably a bigger win.

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595




[Rd] setMethod("Summary")
Prof Brian Ripley