On Thu, Feb 1, 2018 at 12:14 AM, Martin Maechler <maech...@stat.math.ethz.ch> wrote: >>>>>> Michael Lawrence <lawrence.mich...@gene.com> >>>>>> on Tue, 30 Jan 2018 15:57:42 -0800 writes: > > > I just meant that the minimal contract for as.list() appears to be that > it > > returns a VECSXP. To the user, we might say that is.list() will always > > return TRUE. > > Indeed. I also agree with Herv'e that the user level > documentation should rather mention is.list(.) |--> TRUE than > VECSXP, and interestingly for the experts among us, > the is.list() primitive gives not only TRUE for VECSXP but > also of LISTSXP (the good ole' pairlists). > > > I'm not sure we can expect consistency across methods > > beyond that, nor is it feasible at this point to match the > > semantics of the methods package. It deals in "class > > space" while as.list() deals in "typeof() space". > > > Michael > > Yes, and that *is* the extra complexity we have in R (inherited > from S, I'd say) which ideally wasn't there and of course is > not there in much younger languages/systems such as julia. > > And --- by the way let me preach, for the "class space" --- > do __never__ use > > if(class(obj) == "<classname>") > > in your code (I see this so often, shockingly to me ...) but rather use > > if(inherits(obj, "<classname>")) > > instead.
Second this one. But, soon (*) the former will at least give the correct answer when length(class(obj)) == 1 and produce an error otherwise. So, several of these cases will be caught at run-time in a near future. (*) When _R_CHECK_LENGTH_1_CONDITION_=true becomes the default behavior - hopefully by R 3.5.0. > > Martin > > > > > On Tue, Jan 30, 2018 at 3:47 PM, Hervé Pagès <hpa...@fredhutch.org> > wrote: > > >> On 01/30/2018 02:50 PM, Michael Lawrence wrote: > >> > >>> by() does not always return a list. In Gabe's example, it returns an > >>> integer, thus it is coerced to a list. as.list() means that it should > be a > >>> VECSXP, not necessarily with "list" in the class attribute. > >>> > >> > >> The documentation is not particularly clear about what as.list() > >> means for list derivatives. IMO clarifications should stick to > >> simple concepts and formulations like "is.list(x) is TRUE" or > >> "x is a list or a list derivative" rather than "x is a VECSXP". > >> Coercion is useful beyond the use case of implementing a .C entry > >> point and calling as.numeric/as.list/etc... on its arguments. > >> > >> This is why I was hoping that we could maybe discuss the possibility > >> of making the as.list() contract less vague than just "as.list() > >> must return a list or a list derivative". > >> > >> Again, I think that 2 things weight quite a lot in that discussion: > >> 1) as.list() returns an object of class "data.frame" on a > >> data.frame (strict coercion). If all what as.list() needed to > >> do was to return a VECSXP, then as.list.default() already does > >> this on a data.frame so why did someone bother adding an > >> as.list.data.frame method that does strict coercion? > >> 2) The S4 coercion system based on as() does strict coercion by > >> default. > >> > >> H. > >> > >> > >>> Michael > >>> > >>> > >>> On Tue, Jan 30, 2018 at 2:41 PM, Hervé Pagès <hpa...@fredhutch.org > >>> <mailto:hpa...@fredhutch.org>> wrote: > >>> > >>> Hi Gabe, > >>> > >>> Interestingly the behavior of as.list() on by objects seem to > >>> depend on the object itself: > >>> > >>> > b1 <- by(1:2, 1:2, identity) > >>> > class(as.list(b1)) > >>> [1] "list" > >>> > >>> > b2 <- by(warpbreaks[, 1:2], warpbreaks[,"tension"], summary) > >>> > class(as.list(b2)) > >>> [1] "by" > >>> > >>> This is with R 3.4.3 and R devel (2017-12-11 r73889). > >>> > >>> H. > >>> > >>> On 01/30/2018 02:33 PM, Gabriel Becker wrote: > >>> > >>> Dario, > >>> > >>> What version of R are you using. In my mildly old 3.4.0 > >>> installation and in the version of Revel I have lying around > >>> (also mildly old...) I don't see the behavior I think you are > >>> describing > >>> > >>> > b = by(1:2, 1:2, identity) > >>> > >>> > class(as.list(b)) > >>> > >>> [1] "list" > >>> > >>> > sessionInfo() > >>> > >>> R Under development (unstable) (2017-12-19 r73926) > >>> > >>> Platform: x86_64-apple-darwin15.6.0 (64-bit) > >>> > >>> Running under: OS X El Capitan 10.11.6 > >>> > >>> > >>> Matrix products: default > >>> > >>> BLAS: > >>> /Users/beckerg4/local/Rdevel/R > >>> .framework/Versions/3.5/Resources/lib/libRblas.dylib > >>> > >>> LAPACK: > >>> /Users/beckerg4/local/Rdevel/R > >>> .framework/Versions/3.5/Resources/lib/libRlapack.dylib > >>> > >>> > >>> locale: > >>> > >>> [1] > >>> en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 > >>> > >>> > >>> attached base packages: > >>> > >>> [1] stats graphics grDevices utils datasets > >>> methods base > >>> > >>> > >>> loaded via a namespace (and not attached): > >>> > >>> [1] compiler_3.5.0 > >>> > >>> > > >>> > >>> > >>> As for by not having a class definition, no S3 class has an > >>> explicit definition, so this is somewhat par for the course > >>> here... > >>> > >>> did I misunderstand something? > >>> > >>> > >>> ~G > >>> > >>> On Tue, Jan 30, 2018 at 2:24 PM, Hervé Pagès > >>> <hpa...@fredhutch.org <mailto:hpa...@fredhutch.org> > >>> <mailto:hpa...@fredhutch.org <mailto:hpa...@fredhutch.org>>> > >>> wrote: > >>> > >>> I agree that it makes sense to expect as.list() to perform > >>> a "strict coercion" i.e. to return an object of class "list", > >>> *even* on a list derivative. That's what as( , "list") does > >>> by default: > >>> > >>> # on a data.frame object > >>> as(data.frame(), "list") # object of class "list" > >>> # (but strangely it drops the > >>> names) > >>> > >>> # on a by object > >>> x <- by(warpbreaks[, 1:2], warpbreaks[,"tension"], > >>> summary) > >>> as(x, "list") # object of class "list" > >>> > >>> More generally speaking as() is expected to perform "strict > >>> coercion" by default, unless called with 'strict=FALSE'. > >>> > >>> That's also what as.list() does on a data.frame: > >>> > >>> as.list(data.frame()) # object of class "list" > >>> > >>> FWIW as.numeric() also performs "strict coercion" on an > >>> integer > >>> vector: > >>> > >>> as.numeric(1:3) # object of class "numeric" > >>> > >>> So an as.list.env method that does the same as as(x, "list") > >>> would bring a small touch of consistency in an otherwise > >>> quite inconsistent world of coercion methods(*). > >>> > >>> H. > >>> > >>> (*) as(data.frame(), "list", strict=FALSE) doesn't do what > >>> you'd > >>> expect (just one of many examples) > >>> > >>> > >>> On 01/29/2018 05:00 PM, Dario Strbenac wrote: > >>> > >>> Good day, > >>> > >>> I'd like to suggest the addition of an as.list method > >>> for a by > >>> object that actually returns a list of class "list". > >>> This would > >>> make it safer to do type-checking, because is.list also > >>> returns > >>> TRUE for a data.frame variable and using class(result) > >>> == "list" > >>> is an alternative that only returns TRUE for lists. > >>> It's also > >>> confusing initially that > >>> > >>> class(x) > >>> > >>> [1] "by" > >>> > >>> is.list(x) > >>> > >>> [1] TRUE > >>> > >>> since there's no explicit class definition for "by" and no > >>> mention if it has any superclasses. > >>> > >>> -------------------------------------- > >>> Dario Strbenac > >>> University of Sydney > >>> Camperdown NSW 2050 > >>> Australia > > ............. > > >>> -- Gabriel Becker, PhD > >>> Scientist (Bioinformatics) > >>> Genentech Research > >>> > > >> 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: hpa...@fredhutch.org > >> Phone: (206) 667-5791 > >> Fax: (206) 667-1319 > > ______________________________________________ > 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