Re: [Rd] Discrepancy between is.list() and is(x, "list")
Abs, Inline. On Thu, Mar 28, 2019 at 8:10 PM Abs Spurdle wrote: > I know I said that I had no further comments on object oriented semantics. > However, I found a contradiction in the R documentation. > > > Gabriel Becker wrote: > > So, there are implicit classes, but *only when the data object is NOT an > "R object" > > In the R Language Definition: > > The R specific function typeof returns the type of an R object. > > Lists have elements, each of which can contain any type of R object > > Symbols refer to R objects. > > Unlike most other R objects, environments are not copied > > So, according the the R Language Defintion, all objects in R, are R > objects. > > However, in the help page for UseMethod(), which you've already mentioned: > > An R object is a data object which has a class attribute (and this can > be tested by is.object). > > So, according to this, an object in R, isn't necessarily an R object. > > These are contradictory to each other. > And I believe that the R Language Definition is correct. > So, the help page for UseMethod() should be changed to match the language > definition. > This could be changed, but it seems largely semantic. Its clear from the UseMethod documentation that it has a specific definition of "R Object", that it explicitly defines, that it will use throughout that piece of documentation. Unfortunate, perhaps, but clearly scoped and unambiguous, in my opinion. Also, note that if this was changed, its the documentation that would be changed, to simply use, for example "classed object" instead of "R Object". The behavior would be identical and would not change so that all "R objects" (in the language definition sense) would be treated the same by S3 dispatch. > > Hadley Wickham wrote: > > Understanding the distinction between base types and S3 classes > > is very important to make this sort of question precise > > Note that the R Language Definition does not mention either "base types" > or "S3 classes". > So, should I be understanding *your* distinction between them? > They are not Hadley's distinction, or mine. We (he in more detail and covering the corner cases like internal and group generics better) are describing to you how the system actually works, and why you got the results which so surprised you. I think we've done so at this point however, and your phrasing makes it seem like you're looking for an argument, which I (and I suspect others on this list) have no interest in, rather than to learn, which I was happy to try to help you with, so with respect I'll not be engaging you more on this topic. > > Martin Maechler wrote: > > I do agree with Gabe that (in some cases), using > > formal (aka "S4") classes is really what one should do > > S4 doesn't always do intuitive things, either. > > Try the following example: > > library (Matrix) > > m = Matrix (1:24, 4, 6) > > > #expected output > > print (m) > > > #not expected output > > print (m, quote=FALSE) > So the correct way to print S4 objects is with show(), not print. A cursory, non-comprehensive look at print.c (do_defaultprint) suggests to me that print (or rather the c code called by print.default) handles S4 objects when the print call can essentially be transformed in-place to a show call and then evaluated. That is the case where no additional arguments are passed to print: if (*noParam*s && IS_S4_OBJECT(x) && isMethodsDispatchOn()) PrintObject(x, ); else PrintValueRec(x, ); So it has nothing to do with what argument is used, or the quote argument in particular, at all: >* print(x, quote = TRUE)* attr(,"x") [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 attr(,"Dim") [1] 4 6 attr(,"Dimnames") attr(,"Dimnames")[[1]] NULL attr(,"Dimnames")[[2]] NULL attr(,"factors") list() attr(,"class") [1] "dgeMatrix" attr(,"class")attr(,"package") [1] "Matrix" > *print(x, quote = FALSE)* attr(,"x") [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 attr(,"Dim") [1] 4 6 attr(,"Dimnames") attr(,"Dimnames")[[1]] NULL attr(,"Dimnames")[[2]] NULL attr(,"factors") list() attr(,"class") [1] dgeMatrix attr(,"class")attr(,"package") [1] Matrix > *print(x, digits = 5)* attr(,"x") [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 attr(,"Dim") [1] 4 6 attr(,"Dimnames") attr(,"Dimnames")[[1]] NULL attr(,"Dimnames")[[2]] NULL attr(,"factors") list() attr(,"class") [1] "dgeMatrix" attr(,"class")attr(,"package") [1] "Matrix" But basically, don't call print on S4 objects, call show, and everything should work fine. Best, ~G > However, I still may consider using S4, especially where I would otherwise > use a named list. > > > [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
I know I said that I had no further comments on object oriented semantics. However, I found a contradiction in the R documentation. Gabriel Becker wrote: > So, there are implicit classes, but *only when the data object is NOT an "R object" In the R Language Definition: > The R specific function typeof returns the type of an R object. > Lists have elements, each of which can contain any type of R object > Symbols refer to R objects. > Unlike most other R objects, environments are not copied So, according the the R Language Defintion, all objects in R, are R objects. However, in the help page for UseMethod(), which you've already mentioned: > An R object is a data object which has a class attribute (and this can be tested by is.object). So, according to this, an object in R, isn't necessarily an R object. These are contradictory to each other. And I believe that the R Language Definition is correct. So, the help page for UseMethod() should be changed to match the language definition. Hadley Wickham wrote: > Understanding the distinction between base types and S3 classes > is very important to make this sort of question precise Note that the R Language Definition does not mention either "base types" or "S3 classes". So, should I be understanding *your* distinction between them? Martin Maechler wrote: > I do agree with Gabe that (in some cases), using > formal (aka "S4") classes is really what one should do S4 doesn't always do intuitive things, either. Try the following example: > library (Matrix) > m = Matrix (1:24, 4, 6) > #expected output > print (m) > #not expected output > print (m, quote=FALSE) However, I still may consider using S4, especially where I would otherwise use a named list. [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
On Wed, Mar 27, 2019 at 6:27 PM Abs Spurdle wrote: > > > the prison made by ancient design choices > > That prison of ancient design choices isn't so bad. > > I have no further comments on object oriented semantics. > However, I'm planning to follow the following design pattern. > > If I set the class of an object, I will append the new class to the > existing class. > > #good > class (object) = c ("something", class (object) ) > > #bad > class (object) = "something" > > I encourage others to do the same. I don't think this is a good pattern. It's better to clearly define a constructor function that checks that `object` is the correct underlying base type for your class - https://adv-r.hadley.nz/s3.html#s3-classes. Hadley -- http://hadley.nz __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
> Abs Spurdle > on Thu, 28 Mar 2019 12:26:36 +1300 writes: >> the prison made by ancient design choices > That prison of ancient design choices isn't so bad. > I have no further comments on object oriented semantics. > However, I'm planning to follow the following design > pattern. > If I set the class of an object, I will append the new > class to the existing class. > #good class (object) = c ("something", class (object) ) #even better ;-) class(object) <- c("something", class(object)) > #bad class (object) = "something" > I encourage others to do the same. Indeed. BUT also tell the thousands of people who do it -- including somewhat famous R package authors -- *NOT* to use things such as if(class(x) == "Date") or switch(class(x), "Date" = .. , "POSIXct" = .. , ... stop("invalid class: ", class(x))) BUT to always use inherits(x, "") There may be rare exceptions where using class(x)[1] is good, but I have seen many cases where class(x)[1] was used and the R programmers found it smart they knew that class(x) can be of length more than one, but really their code would fail *exactly* because good R programmers do *prepend* their S3 class extension/specialization to the already existing class. --- ... and then, I do agree with Gabe that (in some cases), using formal (aka "S4") classes is really what one should do in order to get a clean interface. Martin Maechler ETH Zurich and R Core Team __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
> the prison made by ancient design choices That prison of ancient design choices isn't so bad. I have no further comments on object oriented semantics. However, I'm planning to follow the following design pattern. If I set the class of an object, I will append the new class to the existing class. #good class (object) = c ("something", class (object) ) #bad class (object) = "something" I encourage others to do the same. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
I would recommend reading https://adv-r.hadley.nz/base-types.html and https://adv-r.hadley.nz/s3.html. Understanding the distinction between base types and S3 classes is very important to make this sort of question precise, and in my experience, you'll find R easier to understand if you carefully distinguish between them. (And hence you shouldn't expect is.x(), inherits(, "x") and is(, "x") to always return the same results) Also note that many of is.*() functions are not testing for types or classes, but instead often have more complex semantics. For example, is.vector() tests for objects with an underlying base vector type that have no attributes (apart from names). is.numeric() tests for objects with base type integer or double, and that have the same algebraic properties as numbers. Hadley On Mon, Mar 25, 2019 at 10:28 PM Abs Spurdle wrote: > > > I have noticed a discrepancy between is.list() and is(x, “list”) > > There's a similar problem with inherits(). > > On R 3.5.3: > > > f = function () 1 > > class (f) = "f" > > > is.function (f) > [1] TRUE > > inherits (f, "function") > [1] FALSE > > I didn't check what happens with: > > class (f) = c ("f", "function") > > However, they should have the same result, regardless. > > > Is this discrepancy intentional? > > I hope not. > > [[alternative HTML version deleted]] > > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel -- http://hadley.nz __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
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 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
Re: [Rd] Discrepancy between is.list() and is(x, "list")
> 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. 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). Furthermore, when you change the class of a vector, list or function, much of the original object's structure and behavior remains. So, it has "Inherited" or "Extended", in my opinion. Resulting in a class hierarchy. > 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. > 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? [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
I think this goes back to SV4 (c. late 1990's). The is. functions are much older (c. mid 1970's) , from before any class system was in S. is() and inherits() were introduced with the S4 class system and were meant to escape from the prison made by ancient design choices. Bill Dunlap TIBCO Software wdunlap tibco.com On Tue, Mar 26, 2019 at 2:11 PM Abs Spurdle wrote: > If I can merge this thread with the one I started yesterday... > > > "If the object does not have a class attribute, it has an implicit > class..." > > which I take to mean that if an object does have a class attribute it > does not also have an implicit class. > > I think this is reasonable behavior. Consider the "Date" class, which > stores values as "numeric": > > > class(Sys.Date()) > > [1] "Date" > > > inherits(Sys.Date(),"numeric") > > [1] FALSE > > > class(unclass(Sys.Date())) > > [1] "numeric" > > > Sys.Date()%%2 > > Error in Ops.Date(Sys.Date(), 2) : %% not defined for "Date" objects > > Letting the modulus operator (as one example) inherit the numeric class > here could create problems. > > I disagree. > A date object should probably extend integers rather than numerics, in the > first place. > However, if it extends numeric, then it extends numeric, otherwise it's a > contradiction. > So, inherits(Sys.Date(),"numeric") should return true. > > Modulo operators should be defined for both dates and numerics. > However, the application of modulo operators to dates, is perhaps unclear, > at least in the general case, anyway. > > > so instead of hitting utils:::head.function, it hits utils:::head.default > > I also see this behavior at least as far aback as 3.5.1, so its not new > to 3.5.3. > > These seem like significant design flaws. > Implicit classes or whatever you want to call them, are clearly part of the > class hierarchy. > > They should be included in inherits(), is() and standard method dispatch, > regardless of whether they are part of the class vector or not. > > Also, is this something that was introduced in R 3.5.1? > The only thing worse than a design flaw is a design flaw that isn't > backward compatible. > > [[alternative HTML version deleted]] > > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
Hi Abs, Lets try to remain civil even when disagreeing about major design philosophies, ok? On Tue, Mar 26, 2019 at 2:08 PM Abs Spurdle wrote: > If I can merge this thread with the one I started yesterday... > > > "If the object does not have a class attribute, it has an implicit > class..." > > which I take to mean that if an object does have a class attribute it > does not also have an implicit class. > > I think this is reasonable behavior. Consider the "Date" class, which > stores values as "numeric": > > > class(Sys.Date()) > > [1] "Date" > > > inherits(Sys.Date(),"numeric") > > [1] FALSE > > > class(unclass(Sys.Date())) > > [1] "numeric" > > > Sys.Date()%%2 > > Error in Ops.Date(Sys.Date(), 2) : %% not defined for "Date" objects > > Letting the modulus operator (as one example) inherit the numeric class > here could create problems. > > I disagree. > A date object should probably extend integers rather than numerics, in the > first place. > However, if it extends numeric, then it extends numeric, otherwise it's a > contradiction. > So, inherits(Sys.Date(),"numeric") should return true. > You seem to be approaching the S3 "class"/dispatch system as something that it is not: a formal class system. S3 dispatch is based, essentially, on labeling, via the class attribute (or, if you like, the value returned by class(), this is basically the same with some fiddly bits for S4, judging by a quick glance at src/main/attrib.c:do_class ). If it is not in the set of class labels, S3 dispatch *will not* treat it as that class. This is by design. An S3 object's "class" also has no* bearing on the contents of the object (* this isn't true for some built in atomic vector classes, as I Recall, but it is for all user defined classes). > mylist = list("hi", "what?") > class(mylist) = "Date" > mylist [1] NA NA *Warning messages:* *1: In as.POSIXlt.Date(x) : NAs introduced by coercion* *2: In as.POSIXlt.Date(x) : NAs introduced by coercion* See? the print method looks at the class attribute of mylist, and says "Oh, this is a Date, I'll use print.Date" and then it craps out (with NAs instead of errors, but still) because the data contained within the object isn't really a "Date". But there is no definition of what it means to be an S3 "Date" object anywhere, other than that it has the Date class attribute. All of the above is *by design*. You're welcome to not like the design. I prefer the formalism of S4, myself, and there are various things I don't love about how S3 works - including some but not all of the things that have come up here. That said, the behaviors are not bugs, and any of the changes you seem to be advocating for would not only break lots of code, but would also represent fundamental changes to the design of a core aspect of the R language. As for doing %% on Dates, I seriously doubt anyone who is operating on Date objects and thinking about times and dates is looking to do a modulo operation in number of Days since Jan 1st 1970, which is what that operation would do. Better to have that fail and if that really, for sure is what the user actually wants to do, they can uncalss it or otherwise convert it to a numeridc first. > Modulo operators should be defined for both dates and numerics. > However, the application of modulo operators to dates, is perhaps unclear, > at least in the general case, anyway. > > > so instead of hitting utils:::head.function, it hits > utils:::head.default > > I also see this behavior at least as far aback as 3.5.1, so its not new > to 3.5.3. > > These seem like significant design flaws. > Implicit classes or whatever you want to call them, are clearly part of > the class hierarchy. > I'm not sure what is clear about that, or what class hierarchy you're talking about in the S3 case. Remember that S3 classes *have no formal definitions at all*. Thats why I rarely if ever use them in software that I write. But it's an important point here. What something would becomes if you unclass()ed it has no bearing on what S3 dispatch will do. > > They should be included in inherits(), is() and standard method dispatch, > regardless of whether they are part of the class vector or not. > Dispatch is ONLY done on the class vector for S3 (AFAIK). Only. That is how S3 dispatch is defined and designed. > > Also, is this something that was introduced in R 3.5.1? > The only thing worse than a design flaw is a design flaw that isn't > backward compatible. > No that is just the non-devel R I had handy, and 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. Before that head() on a function (likely) would have failed just like it still does on your reclassed function. Because, again, this is how S3 is supposed to behave when you give it the inputs you are. I fyou want your f class to hit function S3 methods, you need to do class(myfun) <- c("f", "function")
Re: [Rd] Discrepancy between is.list() and is(x, "list")
If I can merge this thread with the one I started yesterday... > "If the object does not have a class attribute, it has an implicit class..." > which I take to mean that if an object does have a class attribute it does not also have an implicit class. > I think this is reasonable behavior. Consider the "Date" class, which stores values as "numeric": > > class(Sys.Date()) > [1] "Date" > > inherits(Sys.Date(),"numeric") > [1] FALSE > > class(unclass(Sys.Date())) > [1] "numeric" > > Sys.Date()%%2 > Error in Ops.Date(Sys.Date(), 2) : %% not defined for "Date" objects > Letting the modulus operator (as one example) inherit the numeric class here could create problems. I disagree. A date object should probably extend integers rather than numerics, in the first place. However, if it extends numeric, then it extends numeric, otherwise it's a contradiction. So, inherits(Sys.Date(),"numeric") should return true. Modulo operators should be defined for both dates and numerics. However, the application of modulo operators to dates, is perhaps unclear, at least in the general case, anyway. > so instead of hitting utils:::head.function, it hits utils:::head.default > I also see this behavior at least as far aback as 3.5.1, so its not new to 3.5.3. These seem like significant design flaws. Implicit classes or whatever you want to call them, are clearly part of the class hierarchy. They should be included in inherits(), is() and standard method dispatch, regardless of whether they are part of the class vector or not. Also, is this something that was introduced in R 3.5.1? The only thing worse than a design flaw is a design flaw that isn't backward compatible. [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
Hello, Here is another example. df1 <- data.frame(a = 1:3, b = 4:6) inherits(df1, "data.frame") #[1] TRUE class(df1) #[1] "data.frame" inherits(df1, "list") #[1] FALSE This is documented behavior, the help page ?inherits says The function class prints the vector of names of classes an object inherits from. So far, so good. But now comes the part I don't like. is.list(df1) #[1] TRUE Strictly speaking this is not unexpected behavior (because it's documented) but isn't it *inconsistent* behavior? Rui Barradas Às 16:30 de 26/03/2019, Berry, Charles escreveu: In the case of inherits (at least) this seems intended. The help page says: "If the object does not have a class attribute, it has an implicit class..." which I take to mean that if an object does have a class attribute it does not also have an implicit class. The behavior you noted below will apply to other types bearing implicit classes. For example: inherits(1.0, "numeric") [1] TRUE inherits(structure(1.0, class="myclass"), "numeric") [1] FALSE I think this is reasonable behavior. Consider the "Date" class, which stores values as "numeric": class(Sys.Date()) [1] "Date" inherits(Sys.Date(),"numeric") [1] FALSE class(unclass(Sys.Date())) [1] "numeric" Sys.Date()%%2 Error in Ops.Date(Sys.Date(), 2) : %% not defined for "Date" objects Letting the modulus operator (as one example) inherit the numeric class here could create problems. Of course for classes that should inherit the implicit type, it can be explicitly added to the end of the class() vector by its constructor. HTH, Chuck On Mar 25, 2019, at 8:27 PM, Abs Spurdle wrote: I have noticed a discrepancy between is.list() and is(x, “list”) There's a similar problem with inherits(). On R 3.5.3: f = function () 1 class (f) = "f" is.function (f) [1] TRUE inherits (f, "function") [1] FALSE I didn't check what happens with: class (f) = c ("f", "function") However, they should have the same result, regardless. Is this discrepancy intentional? I hope not. [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
In the case of inherits (at least) this seems intended. The help page says: "If the object does not have a class attribute, it has an implicit class..." which I take to mean that if an object does have a class attribute it does not also have an implicit class. The behavior you noted below will apply to other types bearing implicit classes. For example: > inherits(1.0, "numeric") [1] TRUE > inherits(structure(1.0, class="myclass"), "numeric") [1] FALSE > I think this is reasonable behavior. Consider the "Date" class, which stores values as "numeric": > class(Sys.Date()) [1] "Date" > inherits(Sys.Date(),"numeric") [1] FALSE > class(unclass(Sys.Date())) [1] "numeric" > Sys.Date()%%2 Error in Ops.Date(Sys.Date(), 2) : %% not defined for "Date" objects > Letting the modulus operator (as one example) inherit the numeric class here could create problems. Of course for classes that should inherit the implicit type, it can be explicitly added to the end of the class() vector by its constructor. HTH, Chuck > On Mar 25, 2019, at 8:27 PM, Abs Spurdle wrote: > >> I have noticed a discrepancy between is.list() and is(x, “list”) > > There's a similar problem with inherits(). > > On R 3.5.3: > >> f = function () 1 >> class (f) = "f" > >> is.function (f) > [1] TRUE >> inherits (f, "function") > [1] FALSE > > I didn't check what happens with: >> class (f) = c ("f", "function") > > However, they should have the same result, regardless. > >> Is this discrepancy intentional? > > I hope not. > > [[alternative HTML version deleted]] > __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Discrepancy between is.list() and is(x, "list")
> I have noticed a discrepancy between is.list() and is(x, “list”) There's a similar problem with inherits(). On R 3.5.3: > f = function () 1 > class (f) = "f" > is.function (f) [1] TRUE > inherits (f, "function") [1] FALSE I didn't check what happens with: > class (f) = c ("f", "function") However, they should have the same result, regardless. > Is this discrepancy intentional? I hope not. [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] Discrepancy between is.list() and is(x, "list")
Hi R-devel, I have noticed a discrepancy between is.list() and is(x, “list”), which I previously believed to be synonymous. On R version 3.5.2 (2018-12-20): data(iris) is.list(iris)# TRUE is(iris, “list”) # FALSE Is this discrepancy intentional? Kind regards, Shian Su ___ The information in this email is confidential and intended solely for the addressee. You must not disclose, forward, print or use it without the permission of the sender. The Walter and Eliza Hall Institute acknowledges the Wurundjeri people of the Kulin Nation as the traditional owners of the land where our campuses are located and the continuing connection to country and community. ___ [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel