From edd at debian.org  Thu Oct 22 22:53:11 2015
From: edd at debian.org (Dirk Eddelbuettel)
Date: Thu, 22 Oct 2015 15:53:11 -0500
Subject: [Rd] Best way to implement optional functions?
In-Reply-To: <1445544532.4147.22.camel@brian-rcg>
References: <56293F15.80509@gmail.com>
	<1445544532.4147.22.camel@brian-rcg>
Message-ID: <22057.19639.555092.663750@max.nulle.part>


On 22 October 2015 at 15:08, Brian G. Peterson wrote:
| On Thu, 2015-10-22 at 15:55 -0400, Duncan Murdoch wrote:
| > I'm planning on adding some new WebGL functionality to the rgl package, 
| > but it will pull in a very large number of dependencies. Since many 
| > people won't need it, I'd like to make the new parts optional.
| > 
| > The general idea I'm thinking of is to put the new stuff into a separate 
| > package, and have rgl "Suggest" it.  But I'm not sure whether these 
| > functions  should only be available in the new package (so users would 
| > have to attach it to use them), or whether they should be in rgl, but 
| > fail if the new package is not available for loading.
| > 
| > Can people suggest other packages that solve this kind of problem in a 
| > good way?
| 
| We have a number of functions in PerformanceAnalytics or
| PortfolioAnalytics that rely on packages in 'Suggests'.
| 
| The model we have chiefly used is 
| 
| stopifnot("package:MASS" %in% search() || require("MASS",quietly=TRUE))
| 
| of course, it is now no longer recommended to do it this way, so we'll
| probably need to test and load namespaces instead.
| 
| It makes sense to me to have such functions in the main package, and
| provide pointers in the documentation and the error message which
| describe that the other package is required to be available for the
| function to work.

Rcmdr by John Fox has also done this for many years -- and has also moved
back from "everything in Depends (or Imports)" to "most things in Suggests".
As I maintain the package in Debian I had to add a fair number of packages
because the requirement was "hard" (via Depends/Imports) so that the extra
package was needed to actually start Rcmdr.  

Generally, a soft requirement is much better, especially when coupled with
appropriate tests -- eg via requireNamespace("packageName", quietly=TRUE) --
and this can be coupled with notifying the user about the optional package.

Also note that CRAN got itself a new Repo Policy revision where this was added:

    A package listed in `Suggests' or `Enhances' should be used
    conditionally in examples or tests if it cannot straightforwardly be
    installed on the major R platforms.

This is step forward as it recognises that Suggests: need to be tested for.

Sadly it still waters it down via the "not straightforwardly".  But then Rome
wasn't built with a single Policy Revision either ...

Dirk


-- 
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org



[Rd] Best way to implement optional functions?
Dirk Eddelbuettel