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

Martin Maechler m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Fri Nov 15 17:31:15 CET 2019


>>>>> Pages, Herve 
>>>>>     on Thu, 14 Nov 2019 19:13:47 +0000 writes:

    > On 11/14/19 05:47, Hadley Wickham wrote:
    >> On Sun, Nov 10, 2019 at 2:37 AM Martin Maechler
    >> <maechler using 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 can't seem to find the previous thread, so would you mind being a
    >> bit more explicit here? Do you mean adding "array" to the implicit
    >> class?

    > It's late in Europe ;-)

    > That's my understanding. I think the plan is to have class(matrix()) 
    > return c("matrix", "array"). No class attributes added to matrix or 
    > array objects.


    > It's all what is needed to have inherits(matrix(), "array") return TRUE 
    > (instead of FALSE at the moment) and S3 dispatch pick up the foo.array 
    > method when foo(matrix()) is called and there is no foo.matrix method.

Thank you, Hervé!  That's exactly the plan.

    >> Or adding it to the explicit class? Or adding it to inherits?
    >> i.e. which of the following results are you proposing to change?
    >> 
    >> is_array <- function(x) UseMethod("is_array")
    >> is_array.array <- function(x) TRUE
    >> is_array.default <- function(x) FALSE
    >> 
    >> x <- matrix()
    >> is_array(x)
    >> #> [1] FALSE
    >> x <- matrix()
    >> inherits(x, "array")
    >> #> [1] FALSE
    >> class(x)
    >> #> [1] "matrix"
    >> 
    >> It would be nice to make sure this is consistent with the behaviour of
    >> integers, which have an implicit parent class of numeric:

    > I agree but I don't know if Martin wants to go that far for R 4.0. 

again, correct.
In the mean time, thanks to Tomas Kalibera,  my small change has
been tested on all of CRAN and Bioc (Software) packages

  R CMD check <pkg>

but no '--as-cran' nor any  environment variable settings such
as ((strongly recommended by me for package developers !))

      _R_CHECK_LENGTH_1_CONDITION_=true
      _R_CHECK_LENGTH_1_LOGIC2_=verbose

>From the package checks, and my own checks I've started noticing
only today, that indeed, the   _R_CHECK_LENGTH_1_CONDITION_=true
environment variable setting
--- stemming more or less directly from an R-devel (mailing list)
    proposal by  Henrik Bengtsson --
and documented in  help("if")  since R 3.5.0,

*together* with the proposal  of

  class(<matrix>)  |--> c("matrix", "array")

is triggering many new ERRORs because the bad use of    class(.) == "..."
which I've blogged about is very often inside if(), i.e.,

      if (class(object) == "foobar")  # or  ` != ` or 

Now in "new R-devel", and when object is a matrix, 

      if (  class(object)     == "foobar")
<===>
      if (c("matrix","array") == "foobar") 
<===>
      if (c(FALSE, FALSE))

which is "fine" (i.e, just giving the infamous warning.. which
      	 	 is often surpressed by testthat or similar wrappers)
unless you set the env.var .. as I think you R-devel readers all
should do :

    > Sys.unsetenv("_R_CHECK_LENGTH_1_CONDITION_")
    > if(c(FALSE,FALSE)) 1 else 2
    [1] 2
    Warning message:
    In if (c(FALSE, FALSE)) 1 else 2 :
      the condition has length > 1 and only the first element will be used

    > Sys.setenv("_R_CHECK_LENGTH_1_CONDITION_" = TRUE)
    > if(c(FALSE,FALSE)) 1 else 2
    Error in if (c(FALSE, FALSE)) 1 else 2 : the condition has length > 1
    > 

    > Hopefully that's the longer term plan though (maybe for R 4.1?).

I'm not making promises here.
Maybe if we could agree to make the equivalent of
      _R_CHECK_LENGTH_1_CONDITION_=true
R 4.0.0's (unconditional?) default behavior,
then at least the introduction of 

   class(1L)  |--> c("integer", "numeric")

would be less problematic because most of the wrong uses of
if(class(..) == "integer")  would already have been eliminated ...

Martin


    > Note that there are other situations that could follow e.g. 
    > data.frame/list and probably more...

    > H.


    >> is_numeric <- function(x) UseMethod("is_numeric")
    >> is_numeric.numeric <- function(x) TRUE
    >> is_numeric.default <- function(x) FALSE
    >> 
    >> x <- 1L
    >> is_numeric(x)
    >> #> [1] TRUE
    >> inherits(x, "numeric")
    >> #> [1] FALSE
    >> class(x)
    >> #> [1] "integer"
    >> 
    >> Hadley
    >> 

    > -- 
    > 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 using fredhutch.org
    > Phone:  (206) 667-5791
    > Fax:    (206) 667-1319



More information about the R-devel mailing list