cbind is not generic as claimed, omits labels where S has them (PR#239)

Ross Ihaka ihaka@stat.auckland.ac.nz
Sat, 7 Aug 1999 12:37:59 +1200 (NZST)


	From ripley@stats.ox.ac.uk  Sat Aug  7 09:49:12 1999
	Date: Fri, 6 Aug 1999 22:49:07 +0100 (GMT Daylight Time)
	From: Prof Brian D Ripley <ripley@stats.ox.ac.uk>
	To: Ross Ihaka <ihaka@stat.auckland.ac.nz>
	cc: r-devel@stat.math.ethz.ch
	Subject: Re: cbind is not generic as claimed, omits labels where S has them
	 (PR#239)
	MIME-Version: 1.0

	On Sat, 7 Aug 1999, Ross Ihaka wrote:

	> Ok, I have made some changes to cbind/rbind which will support
	> dispatch to other methods.  As part of this I have changed
	> things so that the values passed on are packaged up as
	> (evaluated) promises so that any closure they invoke will
	> be able to use substitute to get text values

	Sorry, are you using `closure' to mean `method' in S (and I thought R)
	terminology? (I thought a function closure involved the environment....)

Technicality : I mean interpreted function.  I'm disallowing dispatch
to functions without at least an interpreted wrapper.  I don't think
this is a real restriction.

	> to use as labels.  What I need is a clear idea of the rules for doing
	> the dispatch.  The picture I have at present is:
	> 
	> 	dispatch.class <- "default"
	> 	for (arg in arg.list) {
	> 		if (arg is an object) {
	> 			arg.class <- class(arg)[1]
	> 			if (there is a method for arg.class) {
	> 				if (dispatch.class == "default")
	> 					class <- arg.class
	> 				else if (args.class != dispatch.class)
	> 					drop through to dispatch
	> 			}
	> 		}
	> 	}
	>     dispatch:
	> 	if (dispatch.class != "default")
	> 		dispatch to appropriate closure
	> 	else
	> 		carry out default actions
	> 
	> This also looks like it sufficiently generic that it could be packaged
	> as a useful function along the lines of "DespatchOrEval" -- perhaps
	> MultiDespatchOrEval.
	> 
	> Does this sound right?

	`right', huh?  That's hard. I had been thinking about multiple
	classes, which bedevil all this (and JMC got rid of for that
	reason, I guess). I think your rules says choose the class of
	the leading argument whose first class has a method, and I
	think that is wrong. Suppose my two args both have class
	c("mts", "ts") and there is no cbind.mts. Then you will
	dispatch the default, even though the normal rules for
	dispatching on the first arg would dispatch cbind.ts.

	I suspect we need to try more than the first method, but have
	no clear picture of what is right. I would dispatch on the
	first arg that had a usable method.

I think I'm shooting for S compatibility here (I'm firmly in both the
compatible and non-compatible camps -- trying to please everyone I
guess).  I believe Peter described what S3 appears to do, and the
above  is my interpretation of what he said.

I think trying to do inheritance by traversing the class vectors
might be asking for trouble.  It would certainly be significantly
more complex and probably slower.

Taking the first arg with a usable method means that cbind(a, b)
could be a significantly different class of object from cbind(b, a).
This is sometimes a nasty surprise for people.  The S3 philosophy
seems to be that in cases of conflict you ignore classes entirely.
That does give a symmetric result.

	Ross


[ Duncan and I talked about implementing a new kind of object system
  -- different from either S3 or S4.  It would look a little more like
  Java.  Definitely a Version 2 project. ]

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._