>>>>> Martin Maechler >>>>> on Wed, 22 May 2019 09:50:10 +0200 writes:
>>>>> William Dunlap >>>>> on Tue, 21 May 2019 12:11:45 -0700 writes: >> Letting a user supply the autoprint function would be nice also. In a way >> you can already do that, using addTaskCallback(), but that doesn't let you >> suppress the standard autoprinting. >> Having the default autoprinting do its own style of method dispatch doesn't >> seem right. > I agree (if I understand correctly what you mean ... ;-) >> Bill Dunlap >> TIBCO Software >> wdunlap tibco.com >> On Tue, May 21, 2019 at 10:50 AM Lionel Henry <lio...@rstudio.com> wrote: >>> FWIW it was the intention of the patch to make printing of unclassed >>> functions consistent with other base types. This was documented in the >>> "patch 3" section: >>> >>> https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17398 > I now vaguely remember. > OTOH, tests/reg-tests-2.R {the "output related" regression tests} > *did* have an explicit test to ensure that print() and > auto-print do the same thing for functions: > print.function <- function(x, ...) { str(x,...); invisible(x) } > print.function > f > rm(print.function) > ## auto-printing and printing differed up to R 2.9.x > so this was not > "an undocumented consequence of an implementation detail" .. > but you are right that it has not been documented explicitly. >>> I think we need a general way to customise auto-printing for base types >>> and even classed objects as that'd be useful for both users and IDEs. > Thank you, Lionel; but I'm not convinced : > I'm pretty sure that all teaching and documentation about S and R > has suggested that print(f) and auto-printing should result in > the same output _ AFAIR also for S4 objects > [unless print() and show() methods were explicitly made to differ.. ? ] >>> However S3 dispatch may not be optimal for this because it essentially >>> requires polluting the global environment with print methods. Maybe >>> it'd make sense to add getOption("autoprint") which should be set to >>> a user- or environment- supplied function. That function would do the >>> dispatch. I'd be happy to send a patch for this, if it makes sense. >>> Best, >>> Lionel > I'd rather we'd work towards the goal that auto printing > and print() should result in identical output : > 1) for unclassed basic objects, i.e., what Bill meant with print.<storageMode> > where maybe print.<typeof> would be a slightly better name; > 2) for S3 classed objects; > 3) for S4 classed objects with no print() method (but possibly a show() one). > Adding an option for autoprinting would render R even less > strictly functional, depending on yet another powerful global option, > and typical R usage would become more different from > 'R --vanilla' even more --- really not a good direction to go in my view. > AFAICS, the above goal would need changes only for case '1)' One relatively simple way (for R core) to reach that goal would be to declare that print.default() will be used in all cases for ``basic classes'' and consequently "forbid" print.<basic>() in the sense that such functions would be regular functions and not be used for (S3) print() method dispatch. {We could define <basic> to be one of the basic SEXPs i.e. typeof() + some of the basic aliases "call", "name", "numeric", (maybe plus "matrix", "array" ..) or we could have a few basic classes for which methods are allowed, e.g. "function", and disallow all others. } That would allow the internal code to remain fast and not have to consider dispatch to user/package provided print.numeric() etc. But that would of course break previous use such as Bill's examples for integer and complex (below). It would be a clear API change, but probably only break didactic code. All "production" code (incl all packages) really should define a _new_ class for having customized printing. Also, correct separation between print() and auto-print may be difficult really if basic objects are involved: > print.numeric <- function(x, ...) { cat("print(<numeric>): "); str(x, ...) } > print(pi, digits = 11) print(<numeric>): num 3.1415926536 > L <- list(pi = pi, i = 1:2) > print(L) $pi [1] 3.141593 $i [1] 1 2 > print(L$pi) print(<numeric>): num 3.14 > and we typically would not want that print()ing large objects with data, i.e., numeric vectors, would have to check for the presence of a print.numeric() method (and if present call it) for all of these ... Martin >>> > On 21 May 2019, at 13:38, William Dunlap via R-devel < >>> r-devel@r-project.org> wrote: >>> > >>> > It also is a problem with storage.modes "integer" and "complex": >>> > >>> > 3.6.0> print.integer <- function(x,...) "integer vector" >>> > 3.6.0> 1:10 >>> > [1] 1 2 3 4 5 6 7 8 9 10 >>> > 3.6.0> print(1:10) >>> > [1] "integer vector" >>> > 3.6.0> >>> > 3.6.0> print.complex <- function(x, ...) "complex vector" >>> > 3.6.0> 1+2i >>> > [1] 1+2i >>> > 3.6.0> print(1+2i) >>> > [1] "complex vector" >>> > >>> > Bill Dunlap >>> > TIBCO Software >>> > wdunlap tibco.com >>> > >>> > >>> > On Tue, May 21, 2019 at 9:31 AM Martin Maechler < >>> maech...@stat.math.ethz.ch> >>> > wrote: >>> > >>> >>>>>>> William Dunlap via R-devel >>> >>>>>>> on Thu, 16 May 2019 11:56:45 -0700 writes: >>> >> >>> >>> In R-3.6.0 autoprinting was changed so that print methods for the >>> >> storage >>> >>> modes are not called when there is no explicit class attribute. >>> >> E.g., >>> >> >>> >>> % R-3.6.0 --vanilla --quiet >>> >>>> print.function <- function(x, ...) { cat("Function with argument >>> >> list "); >>> >>> cat(sep="\n ", head(deparse(args(x)), -1)); invisible(x) } >>> >>>> f <- function(x, ...) { sum( x * seq_along(x) ) } >>> >>>> f >>> >>> function(x, ...) { sum( x * seq_along(x) ) } >>> >>>> print(f) >>> >>> Function with argument list function (x, ...) >>> >> >>> >>> Previous to R-3.6.0 autoprinting did call such methods >>> >>> % R-3.5.3 --vanilla --quiet >>> >>>> print.function <- function(x, ...) { cat("Function with argument >>> >> list "); >>> >>> cat(sep="\n ", head(deparse(args(x)), -1)); invisible(x) } >>> >>>> f <- function(x, ...) { sum( x * seq_along(x) ) } >>> >>>> f >>> >>> Function with argument list function (x, ...) >>> >>>> print(f) >>> >>> Function with argument list function (x, ...) >>> >> >>> >>> Was this intentional? >>> >> >>> >> No, it was not. ... and I've been the one committing the wrong change. >>> >> >>> >> ... Related to the NEWS entries which start >>> >> >>> >> "Changes in print.*() ...." >>> >> >>> >> Thank you Bill, for reporting.... >>> >> >>> >> It's amazing this has not been detected earlier by anybody. >>> >> >>> >> I think it is *only* for functions, not general >>> >> print.<storagemode>() as you were suggesting - right? >>> >> >>> >> Martin >>> >> ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel