[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