> 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]]
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()%%2Error 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 <spurdle.a at gmail.com> 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]] >
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 <spurdle.a at gmail.com> 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 at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
If I can merge this thread with the one I started yesterday...> "If the object does not have a class attribute, it has an implicitclass..."> which I take to mean that if an object does have a class attribute itdoes not also have an implicit class.> I think this is reasonable behavior. Consider the "Date" class, whichstores 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 classhere 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 newto 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]]
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 <spurdle.a at gmail.com> 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 at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel-- http://hadley.nz