# Suggestions for optimizing package dependencies

Heaviness analysis provides hints for reducing the complexity of package dependencies, but how to optimize depends on the specific use of parent packages in the corresponding package. First we need to be aware of that there are scenarios when reduction of heavy parents could not be performed:

1. When a package extends the functionality of a heavy parents, the parent must be its strong parent.
2. A heavy parent provides core functionality to a package.
3. S4 methods or S4 classes are imported from a parent.

Now let’s assume the dependencies from heavy parents can be reduced. We give the following suggestions for reducing them:

1. Re-implement the functions that were imported from heavy parents. Take package mapStats as an example, an extremely heavy parent Hmisc can be observed where Hmisc has a heaviness of 49 which is almost 60% of the total number of required packages of mapStats. If moving Hmisc to “Suggests” of mapStats, the number of strong dependencies can be reduced from 83 to 34. The dependency heaviness analysis shows there is only one function imported from Hmisc. A deep inspection into the source code of mapStats reveals that only a function `capitalize()` from Hmisc is imported to mapStats. `capitalize()` is a simple function that only capitalizes the first letter of a string. The 49 additional dependencies imported from Hmisc can be avoided by simply reimplementing a function `capitalize()` by developer’s own.

2. The previous scenario is actually not very common. More common cases are when heavy parents only provide analysis that are not frequently used in the package, which we call it as “secondary analysis”. We suggest to move heavy parent packages that are less used to “Suggests” and they are only loaded when the corresponding functions are called. Dependency packages listed in “Suggests” by default are not mandatory to be installed, thus, there will be errors when the functions are called but these dependency packages are not installed yet. pkgndep provides a function `check_pkg()` that checks the availability of a package, and if the package has not been installed yet, `check_pkg()` prints friendly messages to guide user to install it.

   Assume `foo()` is a function that uses another function `bar()` from a heavy parent pkg, `foo()` can be written as:

    foo = function(...) {
        check_pkg("pkg", ...)

        pkg::bar(...)
        ...
    }

3. Another way for reducing the package dependencies is to directly copy code from heavy parents. This approach is of course NOT recommended from the aspect of software engineering, but actually it is widely used in CRAN packages.