Skip to content

RFC: methods() and showMethods() {was "debug"}

2 messages · Martin Maechler, Martin Morgan

#
(a new thread, on purpose)
RobG> Hi, I just committed a change to R-devel so that if
    RobG> debug is called on an S3 generic function, all methods
    RobG> will also automatically have debug turned on for them
    RobG> (if they are dispatched to from the generic).

very nice.

    RobG>    I hope to be able to extend this to S4 and a few
    RobG> other cases that are currently not being handled over
    RobG> the next few weeks.

that (S4) will be very useful for me, thank you in advance,
Robert!

A somewhat related issue:
As many of the R-devel readers will know, there has been quite
a nice ongoing effort to make S3 and S4 methods and classes more
compatible.
One issue here, notably for inexperienced programmeRs,
is also the fact that
methods(f) only tells about S3-methods for 'f',
and showMethods(f) only mentions S4 ones.
This is not at all design error, as indeed S3 and S4 dispatch is quite
different (notably as the latter allows multiple dispatch and
hence uses the nice concept of "signature"),
used to be more incompatible and, indeed,  methods(f) *still*
warns, often wrongly, if it finds that f is a (S4) generic function.

As this is an RFC, let me just make a few more propositional
points, and we (R core) will be happy to receive constructive
feedback from outside the core team as well.

Propositions / Ideas :
[ Using the example of having Matrix: 
  library(Matrix)
]

1) methods(f) should become a bit smarter when it sees that f is
   an S4 generic,  and not say,  e.g., for  

  >  methods(qr)
  ...
   'qr' is a formal generic function; S3 methods will not likely be found
  ...

  but rather at least "look" to see if there's an "ANY" method containing
  UseMethod() (*1), 

2) and if there is, or maybe in any case, methods() should then
   also call showMethods() to show the S4 methods;
   or it would suggest the to user to call  'showMethods(..)'

3) showMethods(.) : It could/should  
  a) look for S3 dispatch symptoms such as
     UseMethod(.) in its "ANY" methods
  b) call methods() in any case

  and then possibly mention the result of methods() in any case,
  *plus* ... that's probably the most difficult part ... 
  warn if there are S3 methods {as per 'b)'} that seem not be
  called at all {as per a)}, but that would also have to
  consider .Primitive s with C internal (S3 and S4) dispatch.


As you see, these are partly concrete proposals, partly just
ideas, asking for feedback, from you, experienced 
programmeRs, ...

Martin Maechler, ETH Zurich


---
*1) as there will always be if the  S4 methods
    have been setup properly and *after* the S3 ones.
  This will typically be the case for situations when there are
  old traditional S3 methods in "base R", and a package adds new
  modern S4 methods.
1 day later
#
Martin Maechler <maechler at stat.math.ethz.ch> writes:
Hi Martin --

A couple of thoughts on showMethods and methods, as a preamble.

1. It would be great if showMethods() returned an S4 object so that its
output could be used in a programmatic way.

2. If I

  library(Biobase); library(Matrix)
  showMethods(class="sparseMatrix")

I end up with entries like

  Function "selectSomeIndex":
    <not a generic function>
 
where selectSomeIndex is an unexported generic from Biobase. So it
would be helpful to clarify the output here, probably restricting
methods to those visible to the caller of showMethods.

3. showMethods allows the user to restrict the search to generics
defined in a particular name space, which can be useful.

4. showMethods has an includeDefs argument, which can also be useful
as a shortcut to constructing a second call (to getMethod or
selectMethod) with a potentially complicated argument list to specify
exactly the method to get.

5. methods() reports that 'Non-visible functions are asterisked' but
might provide additional information on how to access these
non-visible functions (e.g., getAnywhere, though here name spaces
might become important).

6. methods(print, "tukeyline") returning all print methods, but not
residuals.tukeyline. I think the behavior one wants is like
showMethods, the intersection of print methods relevant to class
tukeyline.

In terms of the original prompt about methods() functionality, it
would seem that looking for S4 methods, regardless of an ANY-method
would be 'good' since one use case is to understand object
dispatch. Point 1 makes us want to have an object to manipulate, and
then we must decide between S3 and S4 representation, and S4 probably
wins because of the greater flexibility. This might not be palatable to
all, perhaps leading to a smarter methods returning an S3 object and a
smarter showMethods returning an S4 object.

I wonder whether the functionality typically desired by users of
methods() is more analogous to selectMethod, i.e., find and display
the method that my object will be dispatched to, which is related to
4 and 6, above.

Martin