From mtmorgan at fhcrc.org  Sun Feb 26 18:19:38 2012
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Sun, 26 Feb 2012 09:19:38 -0800
Subject: [Rd] Comments on R_exts section 1.6.6,
 Namespaces with S4 classes and methods
Message-ID: <4F4A69AA.9030604@fhcrc.org>

 > R.version.string
[1] "R Under development (unstable) (2012-02-26 r58493)"

In the recent addition "It is important if you export S4 methods that 
the corresponding generics are available: the requirementa on this are 
stricter as from R 2.15.0. You may for example need to import plot from 
graphics to make visible a function to be converted into its implicit 
generic. But it is better practice to make use of the generics exported 
by stats4 as this enables multiple packages to unambiguously set methods 
on those generics."

(note typo on 'requirementa')

I agree that existing generics should be reused.

The advice points to a very unsatisfactory contortion -- use the generic 
from stats4 for a function in graphics!

It is unclear whether the advice is 'use the implicit generic from 
stats4 whenever wanting to define an S4 method on graphics::plot' or 'if 
a package your package depends on creates a generic, use that generic 
instead of creating your own'. The former introduces artificial 
dependencies on stats4, the latter allows for several independently 
defined S4 generics on plot. Neither is satisfactory.

Dozens of Bioconductor packages importFrom(graphics, plot) and 
exportMethods(plot), in addition to other common functions. Our solution 
has been to create a package BiocGenerics whose purpose is to create and 
document otherwise implicit generics of base packages (see ?BiocGenerics 
for a list of generics). Packages then Import: BiocGenerics and 
importFrom(BiocGenerics, plot). This kind of approach, whatever 
limitations of current implementation, seems much better, providing some 
consistency in documentation and application while limiting artificial 
dependencies (to just one, BiocGenerics). Is a methodsGenerics package 
in base R an appropriate direction?


Somewhat earlier in section 1.6.6, the advice offered is "If the generic 
function is not local to this package, either because it was imported as 
a generic function or because the non-generic version has been made 
generic solely to add S4 methods to it (as for functions such as plot in 
the example above), it can be declared via either or both of export or 
exportMethods, but the latter is clearer (and is used in the stats4 
example above)."

I agree that for an explicit generic defined in another package it makes 
sense to exportMethods. When a package creates a generic (as stats4 
does) the better advice is (a) to create an explicit generic via 
setGeneric("plot") (as stats4 does) and (b) to document and export the 
generic, as the generic has consequences above and beyond the method.


Finally, primitive functions are currently singled out for special 
treatment in several sub-clauses of section 1.6.6. Aggregating these 
sub-clauses into a separate paragraph on primitives would be clearer.

Martin
-- 
Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

Location: M1-B861
Telephone: 206 667-2793



[Rd] Comments on R_exts section 1.6.6, Namespaces with S4 classes and methods
Martin Morgan