From hp@ge@ @end|ng |rom |redhutch@org  Tue Nov 12 07:05:22 2019
From: hp@ge@ @end|ng |rom |redhutch@org (Pages, Herve)
Date: Tue, 12 Nov 2019 06:05:22 +0000
Subject: [Rd] class(<matrix>) |--> c("matrix",
 "arrary") [was "head.matrix ..."]
In-Reply-To: <24009.11387.450978.455955@stat.math.ethz.ch>
References: <CAPRVBcxsAkcgr3mDc4skTe8DTxJaYe2xyhk3QMk3odW1MGcyNA@mail.gmail.com>
 <23935.14449.965488.684663@stat.math.ethz.ch>
 <CAPRVBcwMY=GAVfFeCwowQsxP31Y=_B2ducosThN+8V91WESB8Q@mail.gmail.com>
 <20449_1568703158_x8H6qIDG009669_f8285123-371f-5d4b-1281-6cc085dba122@fredhutch.org>
 <22204_1568723392_x8HCSG3F015456_674779E0-B1F6-4DC2-9F1C-D5D48B044B66@mcmaster.ca>
 <AD725242-0FB7-4004-9F16-304E345A363A@mcmaster.ca>
 <23937.1791.389379.103733@stat.math.ethz.ch>
 <CAD4oTHF_e4rtHu0S5bUu38+kQSEHXwun3Sv9-CbK+xN9tSc2hA@mail.gmail.com>
 <CAD4oTHFf7Zp+Xe3jvv7oirLWgZm7ZiSNWZvbrEsqJGfrL6Q2wQ@mail.gmail.com>
 <23993.29737.690600.313456@stat.math.ethz.ch>
 <38105A28-07AE-48F6-A4A4-0C1FCCCBFBDC@gmail.com>
 <23995.62027.969336.196344@stat.math.ethz.ch>
 <CAD4oTHF1+PdJX-Qq=JZwafhGNatDu9AZVD0prCAvyJFL9bLzVg@mail.gmail.com>
 <24007.52264.596794.767557@stat.math.ethz.ch>
 <4059B295-CA2B-408E-9CC8-B0CEA680867C@depauw.edu>
 <86fd2f38-8bd5-d7ea-10c7-edf4eb750720@gmail.com>
 <24009.11387.450978.455955@stat.math.ethz.ch>
Message-ID: <bddab8a8-9430-f050-3f51-985b60cd4df1@fredhutch.org>



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


[Rd] class(<matrix>) |--> c("matrix", "arrary") [was "head.matrix ..."]
Pages, Herve