common base functions stripping S3 class
On 17/11/2014 10:41 AM, Hadley Wickham wrote:
Generally the idea is that the class should be stripped because R has no way of knowing if the new object, for example unique(obj), still has the necessary properties to be considered to be of the same class as obj. Only the author of the class knows that. S4 would help a bit here, but only structurally (it could detect when the object couldn't possibly be of the right class), not semantically.
There are two possible ways that S3 methods could handle subclasses: * preserve by default (would also have preserve all attributes) * drop by default If you could really on either system consistently, I think you could write correct code. It's very hard when the defaults vary. (In other words, I agree with everything you said, except I think if the default was to preserve you could still write correct code)
I don't see how default preserving could work. For example, I might define a "SortedNumbers" class, which is a vector of numbers in non-decreasing order. I could define min() and max() methods for it which would be really fast, because they only need to look at the first or last elements. But a rev() method wouldn't make sense, so I wouldn't define one of those. If the rev() default method left the class as "SortedNumbers", then my min() and max() calculations would end up broken. So maybe I should have defined a rev() method that just stops with an error. But classes don't own methods, so I'd have no way of knowing that someone else defined a new generic (e.g. shuffle()) that broke things. I don't see any way around this within the S3 system. In fact, some default methods do preserve the class, for example the replacement method `[<-`. I could take a SortedNumbers vector of the numbers 1:10, and set element 1 to 11, and end up breaking min() and max(). This is a problem with the current design. Probably we should do a better job of documenting which methods preserve the class and which ones don't. (For example, `[` doesn't preserve the class, even though it would be fine to do so in this example.) But there are a lot of things to do, and this is one thing that is pretty easy to figure out without documentation, so I'd say it's a low priority. Duncan Murdoch