From maechler at stat.math.ethz.ch  Tue Feb  7 14:07:57 2006
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Tue, 7 Feb 2006 14:07:57 +0100
Subject: [Rd] match gets confused by S4 objects
In-Reply-To: <Pine.LNX.4.61.0602061925190.4469@gannet.stats>
References: <m2hd7cjnse.fsf@ziti.local>
	<Pine.LNX.4.61.0602061925190.4469@gannet.stats>
Message-ID: <17384.39853.165572.356541@stat.math.ethz.ch>

>>>>> "BDR" == Prof Brian Ripley <ripley at stats.ox.ac.uk>
>>>>>     on Mon, 6 Feb 2006 19:44:50 +0000 (GMT) writes:

    BDR> An S4 object is just a list with attributes, so a
    BDR> vector type.  match() works with all vector types
    BDR> including lists, as you found out (or could have read).

yes, the internal representation of S4 objects is such -- seen
from a non-S4 perspective.

    BDR> If in the future those proposing it do re-implement an
    BDR> S4 object as an new SEXP then this will change, but for
    BDR> now the cost of detecting objects which might have an
    BDR> S4 class defined somewhere is just too high (and would
    BDR> fall on those who do not use S4 classes).

Just for further explanation, put into other words and a
slightly changed point of view: 

Yes, many R functions get confused by S4 objects, 
most notably,  c()  (!)

 - because they only look at the "internal representation"

 - and because it's expensive to always ``look twice'';
   particularly from the internal C code.
   There's a relatively simple check from R code which we've
   using for str() :

   >> if(has.class <- !is.null(cl <- attr(object, "class"))) { # S3 or S4 class
   >>    ## FIXME: a kludge
   >>    S4 <- !is.null(attr(cl, "package")) || cl == "classRepresentation"
   >>    ## better, but needs 'methods':   length(methods::getSlots(cl)) > 0
   >> }

   which --- when only testing for S4-presence --- you could collapse to

      if(!is.null(cl <- attr(object, "class")) &&
	 (!is.null(attr(cl, "package")) || 
	  cl == "classRepresentation"))     {

	  ...have.S4.object... 

      }

  but note the comment  >>>>   ## FIXME: a kludge   <<<

The solution has been agreed to be changing the internal
representation of S4 objects making them a new SEXP (basic R
"type"); and as Brian alludes to, the problem is that those in
R-core that want to and are able to do this didn't have the time
for that till now.

Martin Maechler, ETH Zurich


    BDR> On Mon, 6 Feb 2006, Seth Falcon wrote:

    >> If one accidentally calls match(x, obj), where obj is any S4 instance,
    >> the result is NA.
    >> 
    >> I was expecting an error because, in general, if a match method is not
    >> defined for a particular S4 class, I don't know what a reasonable
    >> default could be.  Specifically, here's what I see
    >> 
    >> setClass("FOO", representation(a="numeric"))
    >> foo <- new("FOO", a=10)
    >> match("a", foo)
    >> [1] NA
    >> 
    >> And my thinking is that this should be an error, along the lines of
    >> match("a", function(x) x)
    >> 
    >> Unless, of course, a specific method for match, table="FOO" has been
    >> defined.


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

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



[Rd] match gets confused by S4 objects
Martin Maechler