I've been thinking about managing imports when developing a package. I use roxygen2
to manage my imports, and I like to keep the import declarations close to the places where the functions/methods are used, so my code often ends up looking like this:
#' @importFrom PackageA func1 func2
foo <- function(...) {
...
}
#' @importFrom PackageA func1 func3
bar <- function(...) {
...
}
Of course, the scope of the import isn't actually limited to the functions foo
and bar
, they're imported globally for the package I'm developing. So it's sort of a false sense of carefulness, and things can easily get out of sync.
One solution is to simply use double-colon syntax everywhere instead of importing, e.g. always use PackageA::func1
, etc. IMO that's kind of an ugly solution, it goes all the way to the other extreme of importing locally to a single function call.
A great compromise would be what most other languages do - provide a local/lexical import mechanism so that the import is scoped to the code that actually needs it. We can fake it by doing something like:
foo <- function(...) {
func1 <- PackageA::func1
func2 <- PackageA::func2
...
}
bar <- function(...) {
func1 <- PackageA::func1
func3 <- PackageA::func3
...
}
but of course that doesn't use the namespace import mechanism, it just copies another instance of the functions into the current namespace, and it's also a little ugly IMO.
Has anyone thought about this problem more than I have and come up with a solution that plays nice with roxygen2
and the NAMESPACE
file? Have there been any rumblings in the R-core community about creating localized imports as part of the language?