From maechler at stat.math.ethz.ch  Fri Sep 14 10:00:56 2012
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Fri, 14 Sep 2012 10:00:56 +0200
Subject: [Rd] methods cbind2 bind_activation disrupts cbind everywhere
In-Reply-To: <50510B46.90601@fhcrc.org>
References: <50510B46.90601@fhcrc.org>
Message-ID: <20562.58424.868283.735077@stat.math.ethz.ch>

>>>>> Martin Morgan <mtmorgan at fhcrc.org>
>>>>>     on Wed, 12 Sep 2012 15:23:02 -0700 writes:

    > The methods package ?cbind2 includes the instruction to
    > use via methods:::bind_activation(TRUE). 

well, "instruction" only if one wants to magically enable its
use for cbind(), rbind()

    > use via methods:::bind_activation(TRUE). This changes the
    > default definition of cbind globally, disrupting proper
    > evaluation in packages not using cbind2. 

{ really disrupting?  I seem to only recall examples of
  performance loss, but that memory is fading.. }

    > evaluation in packages not using cbind2. Is cbind2 a
    > hold-over from a time when ... could not be used for
    > dispatch? 

Yes, exactly.

As I'm sure you know well, and   ?dotMethods  explains,
the ... dispatch was introduced only in R 2.8.0,
*and* if you read that help page, it is alluded to several times
that the implementation is still not "perfect" because it
entails restrictions, and also because its implementation in
pure R rather than (partially) C.

I had hoped (but not spent work myself, alas!) that there would
be evolution from there on, but it seems we forgot about it.

    > What is a safe way for a package to use cbind2?

to define methods for cbind2 / rbind2, with nice multiple
dispatch on both arguments,  as the 'Matrix' package has been
doing for many years (long before R 2.8.0) --> Matrix/R/bind.R

And then, instead of "bind_activation", 
Matrix now also defines  cBind() & rBind()
as substitutes for cbind(), rbind(),
simply as using  methods:::cbind()  which recursively calls
cbind2(), rbind2().

This has still the big drawback that  cbind() fails on "Matrix"
matrices {and even with quite an unhelpful error message!}, 
and useRs must learn to use cBind() instead....
not ideal, at all.


In an ideal R world, 
1) the "..." S4 dispatch would be improved and made faster
2) that part of Matrix would be rewritten, so that  cbind() and rbind()
   would work via '...' dispatch on both "Matrix" matrices and
   all standard R objects (atomic vectors, "matrix", data.frame,...),
   and the use of cBind() and rBind() could be deprecated.

I also have a vague recollection that '2)' was not just a job to
be done with finite some effort, but rather seemed not easily
achievable with the current restriction of "..." dispatch
needing all arguments to be of the same superclass.
We would have to define

 setGeneric("cbind", signature = "...")
 setGeneric("rbind", signature = "...")

 setMethod("cbind", "Mnumber", function(..., deparse.level=1) {
 ........
 ........
 })

similarly to what I do in the Rmpfr package,
and where "Mnumber" is a *large* class union... defined in
Rmpfr/R/AllClasses.R and if you look in there, you see comments
with FIXME ... basically the solution was +- ok, but not really 
entirely satisfactory to me.

Still, we maybe should really discuss to have the above two
setGeneric()s in 'methods', and possibly also some class union /
superclass  definitions there (that other packages could use!) possibly even
with   
setMethod("cbind", <large-mother-class>, 
          function(..., deparse.level=1) {
	  ......
	  })
and of course the same with rbind().


    > This came up in the context of complex package
    > dependencies in Bioconductor, as detailed in this thread
    > (sorry for the html).

    > https://stat.ethz.ch/pipermail/bioc-devel/2012-September/003617.html

    > -- 
    > Dr. Martin Morgan Fred Hutchinson Cancer Research Center
    > 1100 Fairview Ave. N.  PO Box 19024 Seattle, WA 98109

    > ______________________________________________
    > R-devel at r-project.org mailing list
    > https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] methods cbind2 bind_activation disrupts cbind everywhere
Martin Maechler