Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-28 Thread Gabriel Becker
Abs,

Inline.

On Thu, Mar 28, 2019 at 8:10 PM Abs Spurdle  wrote:

> I know I said that I had no further comments on object oriented semantics.
> However, I found a contradiction in the R documentation.
>
>
> Gabriel Becker wrote:
> > So, there are implicit classes, but *only when the data object is NOT an
> "R object"
>
> In the R Language Definition:
> > The R specific function typeof returns the type of an R object.
> > Lists have elements, each of which can contain any type of R object
> > Symbols refer to R objects.
> > Unlike most other R objects, environments are not copied
>
> So, according the the R Language Defintion, all objects in R, are R
> objects.
>
> However, in the help page for UseMethod(), which you've already mentioned:
> > An R object is a data object which has a class attribute (and this can
> be tested by is.object).
>
> So, according to this, an object in R, isn't necessarily an R object.
>
> These are contradictory to each other.
> And I believe that the R Language Definition is correct.
> So, the help page for UseMethod() should be changed to match the language
> definition.
>

This could be changed, but it seems largely semantic. Its clear from the
UseMethod documentation that it has a specific definition of "R Object",
that it explicitly defines, that it will use throughout that piece of
documentation. Unfortunate, perhaps, but clearly scoped and unambiguous, in
my opinion.

Also, note that if this was changed, its the documentation that would be
changed, to simply use, for example "classed object" instead of "R Object".
The behavior would be identical and would not change so that all "R
objects" (in the language definition sense) would be treated the same by S3
dispatch.


>
> Hadley Wickham wrote:
> > Understanding the distinction between base types and S3 classes
> > is very important to make this sort of question precise
>
> Note that the R Language Definition does not mention either "base types"
> or "S3 classes".
> So, should I be understanding *your* distinction between them?
>

They are not Hadley's distinction, or mine. We (he in more detail and
covering the corner cases like internal and group generics better) are
describing to you how the system actually works, and why you got the
results which so surprised you.

I think we've done so at this point however, and your phrasing makes it
seem like you're looking for an argument, which I (and I suspect others on
this list) have no interest in, rather than to learn, which I was happy to
try to help you with, so with respect I'll not be engaging you more on this
topic.


>
> Martin Maechler wrote:
> > I do agree with Gabe that (in some cases), using
> > formal (aka "S4") classes is really what one should do
>
> S4 doesn't always do intuitive things, either.
>
> Try the following example:
> > library (Matrix)
> > m = Matrix (1:24, 4, 6)
>
> > #expected output
> > print (m)
>
> > #not expected output
> > print (m, quote=FALSE)
>

So the correct way to print S4 objects is with show(), not print. A
cursory, non-comprehensive look at print.c (do_defaultprint) suggests to me
that print (or rather the c code called by print.default) handles S4
objects when the print call can essentially be transformed in-place to a
show call and then evaluated. That is the case where no additional
arguments are passed to print:

  if (*noParam*s && IS_S4_OBJECT(x) && isMethodsDispatchOn())
PrintObject(x, );
 else
PrintValueRec(x, );


So it has nothing to do with what argument is used, or the quote argument
in particular, at all:

>* print(x, quote = TRUE)*



attr(,"x")

 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

attr(,"Dim")

[1] 4 6

attr(,"Dimnames")

attr(,"Dimnames")[[1]]

NULL


attr(,"Dimnames")[[2]]

NULL


attr(,"factors")

list()

attr(,"class")

[1] "dgeMatrix"

attr(,"class")attr(,"package")

[1] "Matrix"


> *print(x, quote = FALSE)*



attr(,"x")

 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

attr(,"Dim")

[1] 4 6

attr(,"Dimnames")

attr(,"Dimnames")[[1]]

NULL


attr(,"Dimnames")[[2]]

NULL


attr(,"factors")

list()

attr(,"class")

[1] dgeMatrix

attr(,"class")attr(,"package")

[1] Matrix


> *print(x, digits = 5)*



attr(,"x")

 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

attr(,"Dim")

[1] 4 6

attr(,"Dimnames")

attr(,"Dimnames")[[1]]

NULL


attr(,"Dimnames")[[2]]

NULL


attr(,"factors")

list()

attr(,"class")

[1] "dgeMatrix"

attr(,"class")attr(,"package")

[1] "Matrix"


But basically, don't call print on S4 objects, call show, and everything
should work fine.

Best,
~G




> However, I still may consider using S4, especially where I would otherwise
> use a named list.
>
>
>

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-28 Thread Abs Spurdle
I know I said that I had no further comments on object oriented semantics.
However, I found a contradiction in the R documentation.


Gabriel Becker wrote:
> So, there are implicit classes, but *only when the data object is NOT an
"R object"

In the R Language Definition:
> The R specific function typeof returns the type of an R object.
> Lists have elements, each of which can contain any type of R object
> Symbols refer to R objects.
> Unlike most other R objects, environments are not copied

So, according the the R Language Defintion, all objects in R, are R objects.

However, in the help page for UseMethod(), which you've already mentioned:
> An R object is a data object which has a class attribute (and this can be
tested by is.object).

So, according to this, an object in R, isn't necessarily an R object.

These are contradictory to each other.
And I believe that the R Language Definition is correct.
So, the help page for UseMethod() should be changed to match the language
definition.


Hadley Wickham wrote:
> Understanding the distinction between base types and S3 classes
> is very important to make this sort of question precise

Note that the R Language Definition does not mention either "base types" or
"S3 classes".
So, should I be understanding *your* distinction between them?


Martin Maechler wrote:
> I do agree with Gabe that (in some cases), using
> formal (aka "S4") classes is really what one should do

S4 doesn't always do intuitive things, either.

Try the following example:
> library (Matrix)
> m = Matrix (1:24, 4, 6)

> #expected output
> print (m)

> #not expected output
> print (m, quote=FALSE)

However, I still may consider using S4, especially where I would otherwise
use a named list.

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-28 Thread Hadley Wickham
On Wed, Mar 27, 2019 at 6:27 PM Abs Spurdle  wrote:
>
> > the prison made by ancient design choices
>
> That prison of ancient design choices isn't so bad.
>
> I have no further comments on object oriented semantics.
> However, I'm planning to follow the following design pattern.
>
> If I set the class of an object, I will append the new class to the
> existing class.
>
> #good
> class (object) = c ("something", class (object) )
>
> #bad
> class (object) = "something"
>
> I encourage others to do the same.

I don't think this is a good pattern. It's better to clearly define a
constructor function that checks that `object` is the correct
underlying base type for your class -
https://adv-r.hadley.nz/s3.html#s3-classes.

Hadley

-- 
http://hadley.nz

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-28 Thread Martin Maechler
> Abs Spurdle 
> on Thu, 28 Mar 2019 12:26:36 +1300 writes:

>> the prison made by ancient design choices
> That prison of ancient design choices isn't so bad.

> I have no further comments on object oriented semantics.
> However, I'm planning to follow the following design
> pattern.

> If I set the class of an object, I will append the new
> class to the existing class.

> #good class (object) = c ("something", class (object) )

#even better ;-)
  
  class(object) <- c("something", class(object))

> #bad class (object) = "something"

> I encourage others to do the same.
Indeed.

BUT also tell the thousands of people who do it -- including
somewhat famous R package authors --

*NOT* to use things such as

  if(class(x) == "Date")

or
  switch(class(x),  
 "Date" = .. ,
 "POSIXct" = .. ,
 
 ...
 stop("invalid class: ", class(x)))

BUT to always use

inherits(x, "")

There may be rare exceptions where using   class(x)[1]   is
good, but I have seen many cases where class(x)[1]  was used
and the R programmers found it smart they knew that
class(x) can be of length more than one, but really their code
would fail *exactly* because good R programmers do *prepend*
their S3 class extension/specialization to the already existing
class.

---

... and then, I do agree with Gabe that (in some cases), using
 formal (aka "S4") classes is really what one should do in order
to get a clean interface.


Martin Maechler
ETH Zurich and R Core Team

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-27 Thread Abs Spurdle
> the prison made by ancient design choices

That prison of ancient design choices isn't so bad.

I have no further comments on object oriented semantics.
However, I'm planning to follow the following design pattern.

If I set the class of an object, I will append the new class to the
existing class.

#good
class (object) = c ("something", class (object) )

#bad
class (object) = "something"

I encourage others to do the same.

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-27 Thread Hadley Wickham
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  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@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



-- 
http://hadley.nz

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-26 Thread Gabriel Becker
Abs et al,

Ok, so I have just gone and re-read the docs again. My language was a more
absolute than it should have been; *however*, I was still correct for the
cases under discussion.

>From ?UseMethod (emphasis mine)

An R object is a data object which has a ‘class’ attribute (and

 this can be tested by ‘is.object’).  A class attribute is a

 character vector giving the names of the classes from which the

 object _inherits_.  *If the object does not have a class attribute,*

* it has an implicit class.*  Matrices and arrays have class

 ‘"matrix"’ or‘"array"’ followed by the class of the underlying

 vector.  Most vectors have class the result of ‘mode(x)’, except

 that integer vectors have class ‘c("integer", "numeric")’ and real

 vectors have class ‘c("double", "numeric")’.


So, there are implicit classes, but *only when the data object is NOT an "R
object" (ie when it does NOT have a class attribute).* So, what I said was
not correct for certain built in classes: matrices, arrays, and some
atomic vectors but IS true of any object you assign a class attribute to
(e.g. by doing class<-() ) When your code classes an object, you have to
give the full desired vector of inheritence in its class attribute.
Anything you leave out just won't be there.

This is the case with your "f" classed object, so it *does not have an
implicit class.*  That is how S3 is designed and intended to work.


On Tue, Mar 26, 2019 at 6:42 PM Abs Spurdle  wrote:

> > you had seemed to be presenting it as something new in 3.5.3. I would be
> surprised if the behavior doesn't go all the way back to whenever
> head.function was added.
>
> My bad.
> I'm just surprised I've never noticed these problems before.
>
> > S3 classes have no formal definitions at all
> > I'm not sure what is clear about that, or what class hierarchy you're
> talking about in the S3 case.
>
> That's questionable.
> One, because it depends on how you define formal definitions.
>

I mean, I guess, in the sense that that is true of any argument anyone ever
makes that uses a term.

For the record here, I'm using "Formal class definition" as an explicit
declaration of how valid objects of a particular class are structured, what
data they contain, and how they behave.

S3 does not have that. IT has only *implicit* class structure/content
definitions based on what methods for that class look for in objects passed
to them. There is no where you can look to figure out what it "means to be
a  class object" in the S3 sense, beyond a nebulous set of methods
which look for various things within an object that supposedly is of that
class.

> x = "not a date"

> class(x) = "Date"

> is(x, "Date")

[1] TRUE


> y = Sys.Date()

> y

[1] "2019-03-26"

> attr(y, "class")

[1] "Date"

> is.object(y)

[1] TRUE


> class(y) = "NonDate"

> y

[1] 17981

attr(,"class")

[1] "NonDate"

> is(y, "Date")

[1] FALSE

> inherits(y, "Date")

[1] FALSE



> And two, because class definitions can exist outside the code itself.
> e.g. As part of an object oriented model.
> (Being "Object Oriented" is just as much about models as it is about
> syntax).
>

Again, I suppose? In fact they have to S3, as I just pointed out above.
But, I really don't see how this is relevant. I doesn't matter what you
have written down on paper, or in documentation, or in your head as a model
about how your S3 classes relate to eachother, because the S3 dispatch
machinery can't see into any of those places. It can only go by what you
put in the class vector, and that is all it is going to go by (for objects
with a class attribute, ie for any "classes" your code defines)


>
> Furthermore, when you change the class of a vector, list or function, much
> of the original object's structure and behavior remains.
>

Conjecture here, since I don't know what exact behaviors you're referring
to, but if they are ostensibly S3 based (ie they are invoved via an S3
generic), its probably becuse they hit *.default methods which call down to
code internal C which operates based on SEXP type, ie they "escape S3
dispatch" in a sense.


> So, it has "Inherited" or "Extended", in my opinion.
>
Resulting in a class hierarchy.
>

You're welcome to have that opinion, but simply put that is now how
inheritance *for the purposes of S3 dispatch* is defined in S3.


>
> > Dispatch is ONLY done on the class vector for S3 (AFAIK)
>

> Incorrect.
> We've already mentioned the example of head.function().
> In general, this dispatch occurs without the presence of a class attribute.
>

I said the class vector, as in what is returned by class().


 > class(rnorm)

[1] "function"

> attr(rnorm, "class")

NULL


I apologize for not more carefully delineating those two things.

That IS consistent with head hitting head.function for a function but
head.default for a "classed function", because according to the definition
of how S3 behaves, your "classed function" doesn't have any implicit
classes, and you didn't 

Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-26 Thread Abs Spurdle
> you had seemed to be presenting it as something new in 3.5.3. I would be
surprised if the behavior doesn't go all the way back to whenever
head.function was added.

My bad.
I'm just surprised I've never noticed these problems before.

> S3 classes have no formal definitions at all
> I'm not sure what is clear about that, or what class hierarchy you're
talking about in the S3 case.

That's questionable.
One, because it depends on how you define formal definitions.
And two, because class definitions can exist outside the code itself.
e.g. As part of an object oriented model.
(Being "Object Oriented" is just as much about models as it is about
syntax).

Furthermore, when you change the class of a vector, list or function, much
of the original object's structure and behavior remains.
So, it has "Inherited" or "Extended", in my opinion.
Resulting in a class hierarchy.

> Dispatch is ONLY done on the class vector for S3 (AFAIK)

Incorrect.
We've already mentioned the example of head.function().
In general, this dispatch occurs without the presence of a class attribute.

> You seem to be approaching the S3 "class"/dispatch system as something
that it is not: a formal class system

If I can diverge...

Where did this term "Formal Class System" come from?
I've never seen it used anywhere else.
Is is specific to R?

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-26 Thread William Dunlap via R-devel
I think this goes back to SV4 (c. late 1990's).  The is.  functions
are much older (c. mid 1970's) , from before any class system was in S.
is() and inherits() were introduced with the S4 class system and were meant
to escape from the prison made by ancient design choices.

Bill Dunlap
TIBCO Software
wdunlap tibco.com


On Tue, Mar 26, 2019 at 2:11 PM Abs Spurdle  wrote:

> If I can merge this thread with the one I started yesterday...
>
> > "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.
> > 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.
>
> 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 new
> to 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]]
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-26 Thread Gabriel Becker
Hi Abs,

Lets try to remain civil even when disagreeing about major design
philosophies, ok?

On Tue, Mar 26, 2019 at 2:08 PM Abs Spurdle  wrote:

> If I can merge this thread with the one I started yesterday...
>
> > "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.
> > 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.
>
> 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.
>

You seem to be approaching the S3 "class"/dispatch system as something that
it is not: a formal class system. S3 dispatch is based, essentially, on
labeling, via the class attribute (or, if you like, the value returned by
class(), this is basically the same with some fiddly bits for S4, judging
by a quick glance at src/main/attrib.c:do_class ). If it is not in the set
of class labels, S3 dispatch *will not* treat it as that class. This is by
design. An S3 object's "class" also has no* bearing on the contents of the
object (* this isn't true for some built in atomic vector classes, as I
Recall, but it is for all user defined classes).


> mylist = list("hi", "what?")

> class(mylist) = "Date"

> mylist

[1] NA NA

*Warning messages:*

*1: In as.POSIXlt.Date(x) : NAs introduced by coercion*


*2: In as.POSIXlt.Date(x) : NAs introduced by coercion*


See? the print method looks at the class attribute of mylist, and says "Oh,
this is a Date, I'll use print.Date" and then it craps out (with NAs
instead of errors, but still) because the data contained within the object
isn't really a "Date". But there is no definition of what it means to be an
S3 "Date" object anywhere, other than that it has the Date class attribute.

All of the above is *by design*. You're welcome to not like the design. I
prefer the formalism of S4, myself, and there are various things I don't
love about how S3 works - including some but not all of the things that
have come up here. That said, the behaviors are not bugs, and any of the
changes you seem to be advocating for would not only break lots of code,
but would also represent fundamental changes to the design of a core aspect
of the R language.

As for doing %% on Dates, I seriously doubt anyone who is operating on Date
objects and thinking about times and dates is looking to do a modulo
operation in number of Days since Jan 1st 1970, which is what that
operation would do. Better to have that fail and if that really, for sure
is what the user actually wants to do, they can uncalss it or otherwise
convert it to a numeridc first.



> 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 new
> to 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.
>

I'm not sure what is clear about that, or what class hierarchy you're
talking about in the S3 case. Remember that S3 classes *have no formal
definitions at all*. Thats why I rarely if ever use them in software that I
write. But it's an important point here. What something would becomes if
you unclass()ed it has no bearing on what S3 dispatch will do.


>
> They should be included in inherits(), is() and standard method dispatch,
> regardless of whether they are part of the class vector or not.
>

Dispatch is ONLY done on the class vector for S3 (AFAIK). Only. That is how
S3 dispatch is defined and designed.

>
> 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.
>

No that is just the non-devel R I had handy, and you had seemed to be
presenting it as something new in 3.5.3. I would be surprised if the
behavior doesn't go all the way back to whenever head.function was added.
Before that head() on a function (likely) would have failed just like it
still does on your reclassed function. Because, again, this is how S3 is
supposed to behave when you give it the inputs you are. I fyou want your f
class to hit function S3 methods, you need to do

class(myfun) <- c("f", "function")


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-26 Thread Abs Spurdle
If I can merge this thread with the one I started yesterday...

> "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.
> 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.

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 new
to 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]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-26 Thread Rui Barradas

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  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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel



__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-26 Thread Berry, Charles
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  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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Discrepancy between is.list() and is(x, "list")

2019-03-25 Thread Abs Spurdle
> 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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] Discrepancy between is.list() and is(x, "list")

2019-03-11 Thread Shian Su
Hi R-devel,

I have noticed a discrepancy between is.list() and is(x, “list”), which I 
previously believed to be synonymous. On R version 3.5.2 (2018-12-20):

data(iris)
is.list(iris)# TRUE
is(iris, “list”) # FALSE

Is this discrepancy intentional?

Kind regards,
Shian Su

___

The information in this email is confidential and intended solely for the 
addressee.
You must not disclose, forward, print or use it without the permission of the 
sender.

The Walter and Eliza Hall Institute acknowledges the Wurundjeri people of the 
Kulin
Nation as the traditional owners of the land where our campuses are located and
the continuing connection to country and community.
___

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel