25 Deprecation Guidelines

In the normal course of software development, functions, classes, methods, or data objects may need to be removed. Here are some guidelines for ensuring that this process is minimally disruptive to your users.

25.1 What to Deprecate?

Any function, class, method, data, or even package that is no longer used or needed.

25.2 When to Follow These Guidelines?

>|--- Bioconductor development cycle ---------------|>
>|--- o feature introduced --- o feature removed ---|>

Note that if you decide against using a function that you had introduced within the same development cycle, you may simply remove the function without following the standard function deprecation guidelines. It is expected that the devel branch be unstable and be subject to API changes without notice (though you may decide to communicate these changes to your users via the Bioconductor support site).

>| Bioconductor RELEASE_X_Y | Bioconductor development cycle |>
>|-- o feature introduced --|----- o feature removed --------|>

However, if a function was published in at least one release version of Bioconductor, these guidelines must be followed. The process of removing a feature such as a function, class, method, or exported package object takes approximately three release cycles (about 18 months).

25.3 How To Deprecate A Function

25.3.1 Step 1: Deprecate the function

When you first decide to deprecate a function, you should mark it as deprecated in the devel branch. Do this by calling .Deprecated() inside the function. To do this, you must provide a replacement function which should be used in place of the old function. Example:

myOldFunc <- function()
{
    .Deprecated("myNewFunc")
    ## use new function, or remainder of myOldFunc
}

This causes a warning to be emitted whenever a user calls myOldFunc(). See ?.Deprecated for more information.

Indicate in the man page of the old function that it has been deprecated, and suggest a replacement function. Be sure the old function is not called in man page examples or vignette code chunks; R CMD check should report this.

\name{MyPkg-deprecated}
\alias{MyPkg-deprecated}
\title{Deprecated functions in package \sQuote{MyPkg}}

\description{
  These functions are provided for compatibility with older versions
  of \sQuote{MyPkg} only, and will be defunct at the next release.
}

\details{

  The following functions are deprecated and will be made defunct; use
  the replacement indicated below:
  \itemize{

    \item{myOldFunc: \code{\link{newFunc}}}

  }
}

25.3.2 Step 2: Mark the function as defunct

In the next release cycle, after your function has been deprecated, it must be made defunct in the devel branch. This means a call to the old function will return an informative error but not run any additional code. Example:

myOldFunc <- function()
{
    .Defunct("myNewFunc")
}

See ?Defunct for more information.

Remove the documentation of the defunct function, and add to a man page such as the following:

\name{MyPkg-defunct}
\alias{myOldFunc}
\title{Defunct functions in package \sQuote{pkg}}
\description{These functions are defunct and no longer available.}

\details{
  Defunct functions are: \code{myOldFunc}
}

25.3.3 Step 3: Remove the function

In the next release cycle, after your function has been marked as defunct, remove it entirely from your package R code and NAMESPACE in the devel branch. Also remove any man page content that documents the function.

Leave the man page from the previous step in place so that

help("MyPkg-defunct")

still shows the list of defunct functions and their appropriate replacements.

25.4 How To Deprecate An S3 Dataset

25.4.1 Step 1 - Create an S3 deprecation class

The initial step of deprecating a dataset is to signal to users that the dataset will no longer be used. Alert the user with a warning message added to its print method. To do this, first add the deprecation class to the dataset object. Note that the class name here is arbitrary but it should be descriptive:

class(pkgDataset) <- c("DeprecatedData", class(pkgDataset))

Then serialize the class as an R object so that it can be loaded in the package:

save(pkgDataset, file = "data/pkgDataset.rda")

or with usethis:

usethis::use_data(pkgDataset, overwrite = TRUE)

25.4.2 Step 2 - Create a print method

Then create a print method for the new class that will print the warning message:

print.DeprecatedData <- function(x, ...) {
    warning("'pkgDataset' dataset is deprecated; see '?newData'")
    NextMethod()
}

It is useful to guide the user to the replacement dataset or functionality that will replace the data in the warning message. Note that this method should be exported in the package’s NAMESPACE file.

25.4.3 Step 3 - Update documentation

After the dataset object has been saved, we update the documentation to reflect the changes and provide additional details and resources for users as necessary. It is recommended to include a “[Deprecated]” label in the data documentation title.

25.4.4 Step 4 - Defunct the dataset

In the following release cycle, upgrade the warning message to an error message to indicate that it is no longer available. The data can then be removed from the package. Remember to update the “[Deprecated]” label in the documentation title to “[Defunct]”.

25.5 How to Deprecate An S4 Dataset

25.5.1 Step 1 - Create an S4 deprecation class

With S4, the process is similar to S3, but we need to create a new class that inherits from the original class with setClass. The class name here is arbitrary but should be descriptive:

.DeprecatedData <-
    setClass("DeprecatedData", contains = "S4Class")

The setClass call creates a generator function which we can then use to create an instance of the new class from the old object:

myS4DataObject <- .DeprecatedData(myS4DataObject)

We then serialize the object to disk so that it can be loaded in the package:

save(myS4DataObject, file = "data/myS4DataObject.rda")

or by using usethis:

usethis::use_data(myS4DataObject, overwrite = TRUE)

25.5.2 Step 2 - Create a show method

Create a show method for the new class that will produce a warning message:

setMethod("show", "DeprecatedData", function(object) {
    warning("This dataset is deprecated; see '?newData'")
    callNextMethod()
})

Note that this method should be exported in the package’s NAMESPACE and the show generic should be imported from the methods package.

Note that steps 3 and 4 are the same as for S3 datasets.

25.6 How to Deprecate a Package

Please see section on Package End of Life Policy