On 15/07/2008 5:19 PM, Kasper Daniel Hansen wrote:
On Jul 15, 2008, at 12:00 PM, Duncan Murdoch wrote:

On 7/15/2008 2:11 PM, Kasper Daniel Hansen wrote:
Using
methods("plot")
 [1] plot.Date*          plot.HoltWinters*   plot.POSIXct*
 [4] plot.POSIXlt*       plot.TukeyHSD       plot.acf*
 [7] plot.data.frame*    plot.decomposed.ts* plot.default
[10] plot.dendrogram*    plot.density        plot.ecdf
[13] plot.factor*        plot.formula*       plot.hclust*
[16] plot.histogram*     plot.isoreg*        plot.lm
[19] plot.medpolish*     plot.mlm            plot.ppr*
[22] plot.prcomp*        plot.princomp*      plot.profile.nls*
[25] plot.spec           plot.spec.coherency plot.spec.phase
[28] plot.stepfun        plot.stl*           plot.table*
[31] plot.ts             plot.tskernel*
   Non-visible functions are asterisked
I don't see plot.function listed. As I read the man page for methods I would say that the search is just looking for functions with the right type of name.
In a package with a NAMESPACE (like the graphics package, where plot.function lives), a function needs to be declared to be an S3method to show up in this list. plot.function is not declared as an S3 method.

I don't know the reason for this, but I assume it's intentional: take a look at the plot() generic: it has special case code to handle functions.

Let me just state that if I do

plot(sin)

plot.function gets called. This looks to me (as a somewhat experienced R user) as a clear case of method dispatching. I call something that I think most of us think of as a generic, with a function argument and I cannot see that possibility when I do a methods("plot"). This use case is not entirely far out - I have just been teaching and wanted to show how I could see what happened when I called plot on sin and lo and behold, plot.function is not in the list of methods("plot")

I can see that there is special code in plot for handling dispatching on a function. I can see that is it handled differently (ie. not with a call to UseMethod) but from my point of view, the call
   plot(sin)
looks and feels like methods dispatching. I would say plot is a generic.

Finally the help page for plot.function states
## S3 method for class 'function':
      plot(x, y = 0, to = 1, from = y, xlim = NULL, ...)

So I think something should be cleaned up here.

I've made attempts in the past to clean this up, and they introduced bugs and/or broke traditional behaviour. See revisions 42827 through 43202 to src/library/graphics/R/plot.R. The big problem is that the function has traditionally worked in a way that (as far as I know) an S3 method can't work, but we'd really like to pretend it is one.

Maybe declaring it as an S3method would be fine, but maybe it would have weird side effects, since it isn't being called by UseMethod. Maybe changing the man page to state correctly that it's not an S3 method would be the best solution, but it acts so much like one that that might be misleading. However, after my last attempt at improvements I'm reluctant to touch it again, though I agree it isn't perfect.

Duncan Murdoch


Kasper

So if this is a bug, I think it's a documentation bug in the ? plot.function man page, where plot.function should be documented to act a lot like an S3 method, but not identically like one: notice the special handling of the y axis label.


If I define a plot.function in my global workspace, methods("plot") picks it up
plot.function = function() {print("blah")}
methods("plot")
 [1] plot.Date*          plot.HoltWinters*   plot.POSIXct*
 [4] plot.POSIXlt*       plot.TukeyHSD       plot.acf*
 [7] plot.data.frame*    plot.decomposed.ts* plot.default
[10] plot.dendrogram*    plot.density        plot.ecdf
[13] plot.factor*        plot.formula*       plot.function
[16] plot.hclust*        plot.histogram*     plot.isoreg*
[19] plot.lm             plot.medpolish*     plot.mlm
[22] plot.ppr*           plot.prcomp*        plot.princomp*
[25] plot.profile.nls*   plot.spec           plot.spec.coherency
[28] plot.spec.phase     plot.stepfun        plot.stl*
[31] plot.table*         plot.ts             plot.tskernel*

Functions declared in the global workspace are handled by patterns on the name, since you can't declare things there: there's no NAMESPACE file.

   Non-visible functions are asterisked
Based on this, I think that methods("plot") should return plot.function, so I am almost ready to take the bug word in my mouth.
When I debug the methods function it gets to the line
S3reg <- ls(get(".__S3MethodsTable__.", envir = defenv), pattern = name) where it searches the .__S3MethodsTable__. object. Consulting the help page it seems that this object is part of the namespace functionality. My guess is that something goes wrong because function is a reserved word?
I don't think so.

Duncan Murdoch
        
Kasper
This has been tested under R-2.7.1 on Mac OS X and under a not too recent version of R-devel under x86_64. My sessionInfo for the Mac version is
sessionInfo()
R version 2.7.1 (2008-06-23)
i386-apple-darwin8.10.1
locale:
en_US.UTF-8/en_US.UTF-8/C/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] tools_2.7.1
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to