0

TLDR

Does rigorous best practice recommend that a proactive R developer explicitly disambiguate all base functions — even the ubiquitously common functions like c() or cat() — within the .R files of their package, using the package::function() convention?


Context

Though a novice developer, I need to create a (proprietary) package in R. The text R Packages (by the authoritative authors Hadley Wickham and Jenny Bryan) has proven extremely helpful (if occasionally deprecated).

I am keen on following best practices from the start, so as to save myself time and effort down the road. As described in the text, the use of the :: operator can prevent current and future conflicts, by disambiguating functions whose names are overloaded. To wit, the authors are careful to introduce each function with the package::function() convention, and they recommend its general use within the .R files of one's package.

However, their code examples often call functions that hail from the base package yet are unaccompanied by base::. Many base functions, like the ubiquitous c() or cat(), are used by R programmers in their sleep and (I imagine) are unlikely to ever be overloaded by a presumptuous developer. Nonetheless, it is confusing to see (for example) the juxtaposition of base::with() against (the base function) print(), all within a few lines of text.

...(These functions are inspired by how base::with() works.)

f <- function(x, sig_digits) {
  # imagine lots of code here
  withr::with_options(
    list(digits = sig_digits),
    print(x)
  )
  # ... and a lot more code here
}

I understand that the purpose of base::with() is to unambiguously introduce the with() function to the reader. However, the absence of base:: (within the code itself) seems to stick out like a sore thumb, when the package is explicitly named for any function called from any other package. Given my inexperience, I don't feel comfortable assuming the authors' intent.

Question

Are the names of base functions sufficiently unique that using this convention — of calling base::function() for every function() within the base package — would not be worth it? That the risk of overloading the functions (at some point in the future) is far outweighed by the inconvenience (and sheer ugliness) of

my_vector <- base::c(1, 2, 3)

throughout one's .R files? If not, is there an established convention that would balance unambiguity with elegance?

As always, I am grateful for any help, especially on this, my first post to Stack Overflow.

  • 1
    tldr: don't worry about it; if it becomes a problem, then fix it – Hong Ooi Mar 13 '21 at 06:10
  • @HongOoi Thanks for the advice! Would you expressly recommend *against* proactively using `base::function()` anyway (to avoid the hassle of going back and fixing it)? – TheGincgoGreco Mar 13 '21 at 06:16
  • I don't follow this convention. But if you do, where do you stop if you extend this to the base package? You will add significant overhead that hurts performance if you prepend every call to rather low-level functions. Also, operators (such as ::) are functions in R. Personally, I prefer rigorous namespace imports. – Roland Mar 13 '21 at 09:57

0 Answers0