[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