Hi Spencer, My 2c. According to the docs, factors are special-cased. Other S3 'classes' could be special-cased, such as Date in your example, I suppose, but it is not clear how what you're describing could be implemented for the general case. Suppose I define an S3 "class" called my_awesome_class, and have a list of 3 of them in it, and no other guarantees are provided. What should, or even could, R do in the case of unlist(list_of_awesomes)? There is no guarantee that I as an S3 developer have provided a c method for my class such that we could say the unlist call above is equivalent (roughly) to do.call(c, list_of_awesomes), nor that I provided any other particular "mash this set of my_awesome_class objects into one". Nor is it even guaranteed that the concept of combining my_awesome_class objects is even coherent, or would produce a new my_awesome_class object when performed if it is. That said, your example was of length one, we could special case (the default method of) unlist so that for x *not a list*, we're guaranteed that identical(unlist(list(x)), x) == TRUE This would simplify certain code, such as the one from your motivating example, but at the cost of making the output of unlist across inputs less consistent and less easy to reason about and predict. In other words the answer to the question "what class is unlist(list_of_awesomes)? " would become "it depends on how many of them are in the list"... That wouldn't be a good thing on balance, imho. Best, ~G On Thu, Dec 8, 2022 at 5:44 PM Spencer Graves < spencer.graves at effectivedefense.org> wrote:> Consider: > > > > str(unlist(list(Sys.Date()))) > num 19334 > > > > str(unlist(list(factor('a')))) > Factor w/ 1 level "a": 1 > > > I naively expected "str(unlist(list(Sys.Date())))" to return an > object of class 'Date'. After some thought, I felt a need to ask this > list if they think that the core R language might benefit from modifying > the language so "str(unlist(list(Sys.Date())))" was of class 'Date', at > least as an option. > > > Comments? > Thanks, > Spencer Graves > > > > sessionInfo() > R version 4.2.2 (2022-10-31) > Platform: x86_64-apple-darwin17.0 (64-bit) > Running under: macOS Big Sur 11.7.1 > > Matrix products: default > LAPACK: > /Library/Frameworks/R.framework/Versions/4.2/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_4.2.2 tools_4.2.2 > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]
Hi, Gabriel: On 12/8/22 8:20 PM, Gabriel Becker wrote:> Hi Spencer, > > My 2c. > > According to the docs, factors are special-cased. Other S3 'classes' > could be special-cased, such as Date in your example, I suppose, but it > is not clear how what you're describing could be implemented for the > general case. > > Suppose I define an S3 "class" called my_awesome_class, and have a list > of 3 of them in it, and no other guarantees are provided. What should, > or even could, R do in the case of unlist(list_of_awesomes)? > > There is no guarantee that I as an S3 developer have provided a c method > for my class such that we could say the unlist call above is equivalent > (roughly) to do.call(c, list_of_awesomes), nor that I provided any other > particular "mash this set of my_awesome_class objects into one". Nor is > it even guaranteed that the concept of combining my_awesome_classobjects > is even coherent, or would produce a new my_awesome_classobject when > performed if it is.What about adding another argument to create, e.g., unlist(x, recursive = TRUE, use.names = TRUE, attributeFunction=NULL) Then assign the assign the results of the current "unlist(x, ...)" to, say, "ux", and follow that by if(!is.null(attributeFunction))attributes(ux) <- attributeFunction(x) return(ux) An alternative could be to have a default attributeFunction, that computes the attributes of each component of x and keeps only the ones that are shared by all components of x. This would be the same as the current behavior for factors IF each component had the same factor levels and would drop attributes that are different between components. For S4 classes, if the attributes were not ALL identical, then all the attributes would be dropped, as with the current behavior. This should not be a problem for S3 generics, because they should always check to make sure all the required attributes are available.> > That said, your example was of length one,My example was of length one to provide a minimal, self-contained example. That was motivated by a more complicated example, which took me a couple of hours to understand why it wasn't working as I expected ;-) Thanks for your reply. Spencer Graves we could special case (the> default method of) unlist so that for x /not a list/, we're guaranteed that > > identical(unlist(list(x)), x) == TRUE > > This would simplify certain code, such as the one from your motivating > example, but at the cost of making the output of unlist across inputs > less consistent and less easy to reason about and predict. In other > words the answer to the question "what class is > unlist(list_of_awesomes)? " would become "it depends on how many of them > are in the list"... That wouldn't be a good thing on balance, imho. > > Best, > ~G > > On Thu, Dec 8, 2022 at 5:44 PM Spencer Graves > <spencer.graves at effectivedefense.org > <mailto:spencer.graves at effectivedefense.org>> wrote: > > Consider: > > > ?> str(unlist(list(Sys.Date()))) > ? num 19334 > > > ?> str(unlist(list(factor('a')))) > ? Factor w/ 1 level "a": 1 > > > ? ? ? ? ? I naively expected "str(unlist(list(Sys.Date())))" to > return an > object of class 'Date'.? After some thought, I felt a need to ask this > list if they think that the core R language might benefit from > modifying > the language so "str(unlist(list(Sys.Date())))" was of class 'Date', at > least as an option. > > > ? ? ? ? ? Comments? > ? ? ? ? ? Thanks, > ? ? ? ? ? Spencer Graves > > > ?> sessionInfo() > R version 4.2.2 (2022-10-31) > Platform: x86_64-apple-darwin17.0 (64-bit) > Running under: macOS Big Sur 11.7.1 > > Matrix products: default > LAPACK: > /Library/Frameworks/R.framework/Versions/4.2/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_4.2.2 tools_4.2.2 > > ______________________________________________ > R-devel at r-project.org <mailto:R-devel at r-project.org> mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > <https://stat.ethz.ch/mailman/listinfo/r-devel> >
On 08/12/2022 9:20 p.m., Gabriel Becker wrote:> Hi Spencer, > > My 2c. > > According to the docs, factors are special-cased. Other S3 'classes' could > be special-cased, such as Date in your example, I suppose, but it is not > clear how what you're describing could be implemented for the general case. > > Suppose I define an S3 "class" called my_awesome_class, and have a list of > 3 of them in it, and no other guarantees are provided. What should, or even > could, R do in the case of unlist(list_of_awesomes)? > > There is no guarantee that I as an S3 developer have provided a c method > for my class such that we could say the unlist call above is equivalent > (roughly) to do.call(c, list_of_awesomes), nor that I provided any other > particular "mash this set of my_awesome_class objects into one". Nor is it > even guaranteed that the concept of combining my_awesome_class objects is > even coherent, or would produce a new my_awesome_class object when > performed if it is.For the non-recursive case of unlist, do.call(c, list_of_awesomes) is a pretty reasonable expectation. Wouldn't the simplest change be to make no change to unlist, but suggest this alternative in the documentation? Duncan Murdoch> > That said, your example was of length one, we could special case (the > default method of) unlist so that for x *not a list*, we're guaranteed that > > identical(unlist(list(x)), x) == TRUE > > This would simplify certain code, such as the one from your motivating > example, but at the cost of making the output of unlist across inputs less > consistent and less easy to reason about and predict. In other words the > answer to the question "what class is unlist(list_of_awesomes)? " would > become "it depends on how many of them are in the list"... That wouldn't be > a good thing on balance, imho. > > Best, > ~G > > On Thu, Dec 8, 2022 at 5:44 PM Spencer Graves < > spencer.graves at effectivedefense.org> wrote: > >> Consider: >> >> >> > str(unlist(list(Sys.Date()))) >> num 19334 >> >> >> > str(unlist(list(factor('a')))) >> Factor w/ 1 level "a": 1 >> >> >> I naively expected "str(unlist(list(Sys.Date())))" to return an >> object of class 'Date'. After some thought, I felt a need to ask this >> list if they think that the core R language might benefit from modifying >> the language so "str(unlist(list(Sys.Date())))" was of class 'Date', at >> least as an option. >> >> >> Comments? >> Thanks, >> Spencer Graves >> >> >> > sessionInfo() >> R version 4.2.2 (2022-10-31) >> Platform: x86_64-apple-darwin17.0 (64-bit) >> Running under: macOS Big Sur 11.7.1 >> >> Matrix products: default >> LAPACK: >> /Library/Frameworks/R.framework/Versions/4.2/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_4.2.2 tools_4.2.2 >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel