[Rd] print.<strorageMode>() not called when autoprinting
Martin Maechler
m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Wed May 22 13:15:27 CEST 2019
>>>>> 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 <lionel using 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 using 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 <
>>> maechler using 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
>>> >>
More information about the R-devel
mailing list