Abs et al, Ok, so I have just gone and re-read the docs again. My language was a more absolute than it should have been; *however*, I was still correct for the cases under discussion.
>From ?UseMethod (emphasis mine) An R object is a data object which has a ‘class’ attribute (and this can be tested by ‘is.object’). A class attribute is a character vector giving the names of the classes from which the object _inherits_. *If the object does not have a class attribute,* * it has an implicit class.* Matrices and arrays have class ‘"matrix"’ or‘"array"’ followed by the class of the underlying vector. Most vectors have class the result of ‘mode(x)’, except that integer vectors have class ‘c("integer", "numeric")’ and real vectors have class ‘c("double", "numeric")’. So, there are implicit classes, but *only when the data object is NOT an "R object" (ie when it does NOT have a class attribute).* So, what I said was not correct for certain built in classes: matrices, arrays, and some atomic vectors but IS true of any object you assign a class attribute to (e.g. by doing class<-() ) When your code classes an object, you have to give the full desired vector of inheritence in its class attribute. Anything you leave out just won't be there. This is the case with your "f" classed object, so it *does not have an implicit class.* That is how S3 is designed and intended to work. On Tue, Mar 26, 2019 at 6:42 PM Abs Spurdle <spurdl...@gmail.com> wrote: > > you had seemed to be presenting it as something new in 3.5.3. I would be > surprised if the behavior doesn't go all the way back to whenever > head.function was added. > > My bad. > I'm just surprised I've never noticed these problems before. > > > S3 classes have no formal definitions at all > > I'm not sure what is clear about that, or what class hierarchy you're > talking about in the S3 case. > > That's questionable. > One, because it depends on how you define formal definitions. > I mean, I guess, in the sense that that is true of any argument anyone ever makes that uses a term. For the record here, I'm using "Formal class definition" as an explicit declaration of how valid objects of a particular class are structured, what data they contain, and how they behave. S3 does not have that. IT has only *implicit* class structure/content definitions based on what methods for that class look for in objects passed to them. There is no where you can look to figure out what it "means to be a ____ class object" in the S3 sense, beyond a nebulous set of methods which look for various things within an object that supposedly is of that class. > x = "not a date" > class(x) = "Date" > is(x, "Date") [1] TRUE > y = Sys.Date() > y [1] "2019-03-26" > attr(y, "class") [1] "Date" > is.object(y) [1] TRUE > class(y) = "NonDate" > y [1] 17981 attr(,"class") [1] "NonDate" > is(y, "Date") [1] FALSE > inherits(y, "Date") [1] FALSE > And two, because class definitions can exist outside the code itself. > e.g. As part of an object oriented model. > (Being "Object Oriented" is just as much about models as it is about > syntax). > Again, I suppose? In fact they have to S3, as I just pointed out above. But, I really don't see how this is relevant. I doesn't matter what you have written down on paper, or in documentation, or in your head as a model about how your S3 classes relate to eachother, because the S3 dispatch machinery can't see into any of those places. It can only go by what you put in the class vector, and that is all it is going to go by (for objects with a class attribute, ie for any "classes" your code defines) > > Furthermore, when you change the class of a vector, list or function, much > of the original object's structure and behavior remains. > Conjecture here, since I don't know what exact behaviors you're referring to, but if they are ostensibly S3 based (ie they are invoved via an S3 generic), its probably becuse they hit *.default methods which call down to code internal C which operates based on SEXP type, ie they "escape S3 dispatch" in a sense. > So, it has "Inherited" or "Extended", in my opinion. > Resulting in a class hierarchy. > You're welcome to have that opinion, but simply put that is now how inheritance *for the purposes of S3 dispatch* is defined in S3. > > > Dispatch is ONLY done on the class vector for S3 (AFAIK) > > Incorrect. > We've already mentioned the example of head.function(). > In general, this dispatch occurs without the presence of a class attribute. > I said the class vector, as in what is returned by class(). > class(rnorm) [1] "function" > attr(rnorm, "class") NULL I apologize for not more carefully delineating those two things. That IS consistent with head hitting head.function for a function but head.default for a "classed function", because according to the definition of how S3 behaves, your "classed function" doesn't have any implicit classes, and you didn't declare that it inherited from the function class. The portion that is incorrect with what I said is that if the data object is NOT an R object, (ie it is an unclassed atomic vector or other built in type - is.object() returns FALSE ) it MAY have an implicit class which will affect S3 dispatch. But your "f" classed object does not. > You seem to be approaching the S3 "class"/dispatch system as something > that it is not: a formal class system > > If I can diverge... > > Where did this term "Formal Class System" come from? > I've never seen it used anywhere else. > Is is specific to R? > No. I'm not using it as a term of art at all, really. I'm using it to mean explicit, non-implicit, that classes declare formal required internal structures, etc. Best, ~G [[alternative HTML version deleted]] ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel