Martin Maechler
2019-Nov-11 09:40 UTC
[Rd] class(<matrix>) |--> c("matrix", "arrary") [was "head.matrix ..."]
>>>>> Duncan Murdoch >>>>> on Sun, 10 Nov 2019 11:48:26 -0500 writes:> On 10/11/2019 9:17 a.m., Bryan Hanson wrote: >> >> >>> On Nov 10, 2019, at 3:36 AM, Martin Maechler <maechler at stat.math.ethz.ch> wrote: >>> >>>>>>>> Gabriel Becker >>>>>>>> on Sat, 2 Nov 2019 12:37:08 -0700 writes: >>> >>>> I agree that we can be careful and narrow and still see a >>>> nice improvement in behavior. While Herve's point is valid >>>> and I understand his frustration, I think staying within >>>> the matrix vs c(matrix, array) space is the right scope >>>> for this work in terms of fiddling with inheritance. >>> >>> [.................] >>> >>> >>>>> Also, we seem to have a rule that inherits(x, c) iff c %in% class(x), >>>> >>>> good point, and that's why my usage of inherits(.,.) was not >>>> quite to the point. [OTOH, it was to the point, as indeed from >>>> the ?class / ?inherits docu, S3 method dispatch and inherits >>>> must be consistent ] >>>> >>>>> which would break -- unless we change class(x) to return the whole >>>> set of inherited classes, which I sense that we'd rather not do.... >>> >>> [................] >>> >>>> Note again that both "matrix" and "array" are special [see ?class] as >>>> being of __implicit class__ and I am considering that this >>>> implicit class behavior for these two should be slightly >>>> changed .... >>>> >>>> And indeed I think you are right on spot and this would mean >>>> that indeed the implicit class >>>> "matrix" should rather become c("matrix", "array"). >>> >>> I've made up my mind (and not been contradicted by my fellow R >>> corers) to try go there for R 4.0.0 next April. >>> >>> I've found the few places in base R that needed a change (to >>> pass 'make check-all' in the R sources) and found that indeed a >>> overzealous check in 'Matrix' needed also a change (a place >>> where the checking code assume class(<matrix>) |--> "matrix" ). >>> >>> There are certainly many more package (codes and checks) that >>> need adaption .. i.e., should be changed rather *before* the >>> above change is activated in R-devel (and then will affect all CRAN >>> and Bioconductor checks.) >>> >>> To this end, I've published an 'R Blog' yesterday, >>> >>> http://bit.ly/R_blog_class_think_2x >>> >>> which translates to >>> >>> https://developer.r-project.org/Blog/public/2019/11/09/when-you-think-class.-think-again/index.html >>> >>> notably mentioning why using class(x) == "...." (or '!=') or >>> switch(class(.) ...) is quite unsafe and hence bad and you >>> should very often not replace class(x) by class(x)[1] but >>> really use the "only truly correct" ;-) >>> >>> inherits(x, "...") >>> or >>> is(x, "....") # if you're advanced/brave enough (:-) to >>> # use formal classes (S4) >> >> Thanks for the helpful blog post Martin. Is the following >> >> ?test_class? %in% class(some_object) >> >> which I think in your symbols would be >> >> ??? %in% class(x) >> >> safe as far as you see it? By safe, I mean equivalent to your suggestion of inherits(x, ???) . > Those aren't equivalent if S4 gets involved. You can see it if you run > this code: > example("new") # Creates an object named t2 of class "trackcurve" > # that contains "track" > inherits(t2, "track") # TRUE > "track" %in% class(t2) # FALSE > I can't think of any examples not involving S4. > Duncan Murdoch Thank you, Duncan. That's definitely a strong reason for inherits(), because often in such code, you don't know in advance what objects will be passed to your function. On Twitter, others have asked "the same", arguing that "<someclass>" %in% class(.)> uses usual syntax, and thus looks less intimidating than > inherit() and less cryptic than is()I think you should all use -- and *teach* -- inherits(.) more often, and it would no longer be intimidating. Also, for the speed fetishists: inherits() will typically be slightly (but significantly) faster than ` %in% class(.) ` Martin
Pages, Herve
2019-Nov-12 06:05 UTC
[Rd] class(<matrix>) |--> c("matrix", "arrary") [was "head.matrix ..."]
On 11/11/19 01:40, Martin Maechler wrote:>>>>>> Duncan Murdoch >>>>>> on Sun, 10 Nov 2019 11:48:26 -0500 writes: > > > On 10/11/2019 9:17 a.m., Bryan Hanson wrote: > >> > >> > >>> On Nov 10, 2019, at 3:36 AM, Martin Maechler <maechler at stat.math.ethz.ch> wrote: > >>> > >>>>>>>> Gabriel Becker > >>>>>>>> on Sat, 2 Nov 2019 12:37:08 -0700 writes: > >>> > >>>> I agree that we can be careful and narrow and still see a > >>>> nice improvement in behavior. While Herve's point is valid > >>>> and I understand his frustration, I think staying within > >>>> the matrix vs c(matrix, array) space is the right scope > >>>> for this work in terms of fiddling with inheritance. > >>> > >>> [.................] > >>> > >>> > >>>>> Also, we seem to have a rule that inherits(x, c) iff c %in% class(x), > >>>> > >>>> good point, and that's why my usage of inherits(.,.) was not > >>>> quite to the point. [OTOH, it was to the point, as indeed from > >>>> the ?class / ?inherits docu, S3 method dispatch and inherits > >>>> must be consistent ] > >>>> > >>>>> which would break -- unless we change class(x) to return the whole > >>>> set of inherited classes, which I sense that we'd rather not do.... > >>> > >>> [................] > >>> > >>>> Note again that both "matrix" and "array" are special [see ?class] as > >>>> being of __implicit class__ and I am considering that this > >>>> implicit class behavior for these two should be slightly > >>>> changed .... > >>>> > >>>> And indeed I think you are right on spot and this would mean > >>>> that indeed the implicit class > >>>> "matrix" should rather become c("matrix", "array"). > >>> > >>> I've made up my mind (and not been contradicted by my fellow R > >>> corers) to try go there for R 4.0.0 next April. > >>> > >>> I've found the few places in base R that needed a change (to > >>> pass 'make check-all' in the R sources) and found that indeed a > >>> overzealous check in 'Matrix' needed also a change (a place > >>> where the checking code assume class(<matrix>) |--> "matrix" ). > >>> > >>> There are certainly many more package (codes and checks) that > >>> need adaption .. i.e., should be changed rather *before* the > >>> above change is activated in R-devel (and then will affect all CRAN > >>> and Bioconductor checks.) > >>> > >>> To this end, I've published an 'R Blog' yesterday, > >>> > >>> https://urldefense.proofpoint.com/v2/url?u=http-3A__bit.ly_R-5Fblog-5Fclass-5Fthink-5F2x&d=DwIDaQ&c=eRAMFD45gAfqt84VtBcfhQ&r=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA&m=Haem9CPNVAwtpdrnFb50tn-RoEohzBVpzJRgkjRFqBg&s=TFCIJjbe482LLMV-P2B9vTc5G8nIcW0Ekx25qhuzCOg&e> >>> > >>> which translates to > >>> > >>> https://urldefense.proofpoint.com/v2/url?u=https-3A__developer.r-2Dproject.org_Blog_public_2019_11_09_when-2Dyou-2Dthink-2Dclass.-2Dthink-2Dagain_index.html&d=DwIDaQ&c=eRAMFD45gAfqt84VtBcfhQ&r=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA&m=Haem9CPNVAwtpdrnFb50tn-RoEohzBVpzJRgkjRFqBg&s=kbZV1cxdT0uFW2gX8iCQmV-SANS8xCp678it1okCRqs&e> >>> > >>> notably mentioning why using class(x) == "...." (or '!=') or > >>> switch(class(.) ...) is quite unsafe and hence bad and you > >>> should very often not replace class(x) by class(x)[1] but > >>> really use the "only truly correct" ;-) > >>> > >>> inherits(x, "...") > >>> or > >>> is(x, "....") # if you're advanced/brave enough (:-) to > >>> # use formal classes (S4) > >> > >> Thanks for the helpful blog post Martin. Is the following > >> > >> ?test_class? %in% class(some_object) > >> > >> which I think in your symbols would be > >> > >> ??? %in% class(x) > >> > >> safe as far as you see it? By safe, I mean equivalent to your suggestion of inherits(x, ???) . > > > Those aren't equivalent if S4 gets involved. You can see it if you run > > this code: > > > example("new") # Creates an object named t2 of class "trackcurve" > > # that contains "track" > > > inherits(t2, "track") # TRUE > > "track" %in% class(t2) # FALSE > > > I can't think of any examples not involving S4. > > > Duncan Murdoch > > Thank you, Duncan. > That's definitely a strong reason for inherits(), because often > in such code, you don't know in advance what objects will be > passed to your function. > > > On Twitter, others have asked "the same", arguing that > > "<someclass>" %in% class(.) > >> uses usual syntax, and thus looks less intimidating than >> inherit() and less cryptic than is()%-/ (<- ASCII version of the rolling eyes emoji) <ranting mode> The most cryptic of the 3 forms being by far: "<someclass>" %in% class(x) You need to be able to read thru this to understand that the intend is to find out whether 'x' belongs to class "<someclass>" or to one of its subclasses. What could be more natural and readable than using inherits(x, "<someclass>") for that? What's unusual or intimidating about its syntax? OK I could see that maybe some people would like to be able to use a binary operator instead of a function call for this (a la instanceof in Java): `%inherits%` <- inherits library(data.table) x <- data.table() x %inherits% "data.frame" [1] TRUE which would be a reasonable request (looks cute). But trying to make the case for "<someclass>" %in% class(x) on Twitter??! %-/ </ranting mode> H.> > I think you should all use -- and *teach* -- > inherits(.) more often, and it would no longer be intimidating. > > Also, for the speed fetishists: inherits() will typically be > slightly (but significantly) faster than ` %in% class(.) ` > > Martin > > ______________________________________________ > R-devel at r-project.org mailing list > https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel&d=DwIDaQ&c=eRAMFD45gAfqt84VtBcfhQ&r=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA&m=Haem9CPNVAwtpdrnFb50tn-RoEohzBVpzJRgkjRFqBg&s=leJubS1ZTBLker3GGD9hOhoXb4NCoydeg_wIUDg8cHs&e>-- Herv? Pag?s Program in Computational Biology Division of Public Health Sciences Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N, M1-B514 P.O. Box 19024 Seattle, WA 98109-1024 E-mail: hpages at fredhutch.org Phone: (206) 667-5791 Fax: (206) 667-1319
Abby Spurdle
2019-Nov-12 20:21 UTC
[Rd] class(<matrix>) |--> c("matrix", "arrary") [was "head.matrix ..."]
<polite mode>> x %inherits% "data.frame"IMHO, I think that user-defined binary operators are being over-used within the R community. I don't think that they're "cute" or stylish. I think their use should be limited to cases, where they significantly increase the readability of the code. However, readability, is a (partly) subjective topic... </pilote mode>
Possibly Parallel Threads
- class(<matrix>) |--> c("matrix", "arrary") [was "head.matrix ..."]
- class(<matrix>) |--> c("matrix", "arrary") [was "head.matrix ..."]
- class(<matrix>) |--> c("matrix", "arrary") [was "head.matrix ..."]
- class(<matrix>) |--> c("matrix", "arrary") [was "head.matrix ..."]
- class(<matrix>) |--> c("matrix", "arrary") [was "head.matrix ..."]