Is It a Good Practice to Call Functions in a Package via ::

Is it a good practice to call functions in a package via ::

It all depends on context.

:: is primarily necessary if there are namespace collisions, functions from different packages with the same name. When I load the dplyr package, it provides a function filter, which collides with (and masks) the filter function loaded by default in the stats package. So if I want to use the stats version of the function, I'll need to call it with stats::filter. This also gives motivation for not loading lots of packages. If you really only want one function from a package, it can be better to use :: than load the whole package, especially if you know the package will mask other functions you want to use.

Not in code, but in text, I do find :: very useful. It's much more concise to type stats::filter than "the filter function in the stats package".

From a performance perspective, there is a (very) small price for using ::. Long-time R-Core development team member Martin Maechler wrote (on the r-devel mailing list (Sept 2017))

Many people seem to forget that every use of :: is an R
function call and using it is inefficient compared to just using
the already imported name.

The performance penalty is very small, on the order of a few microseconds, so it's only a concern when you need highly optimized code. Running a line of code that uses :: one million times will take a second or two longer than code that doesn't use ::.

As far as portability goes, it's nice to explicitly load packages at the top of a script because it makes it easy to glance at the first few lines and see what packages are needed, installing them if necessary before getting too deep in anything else, i.e., getting halfway through a long process that now can't be completed without starting over.

Aside: a similar argument can be made to prefer library() over require(). Library will cause an error and stop if the package isn't there, whereas require will warn but continue. If your code has a contingency plan in case the package isn't there, then by all means use if (require(package)) ..., but if your code will fail without a package you should use library(package) at the top so it fails early and clearly.

Within your own package

The general solution is to make your own package that imports the other packages you need to use in the DESCRIPTION file. Those packages will be automatically installed when your package is installed, so you can use pkg::fun internally. Or, by also importing them in the NAMESPACE file, you can import an entire package or selectively importFrom specific functions and not need ::. Opinions differ on this. Martin Maechler (same r-devel source as above) says:

Personally I've got the impression that :: is
much "overused" nowadays, notably in packages where I'd strongly
advocate using importFrom() in NAMESPACE, so all this happens
at package load time, and then not using :: in the package
sources itself.

On the other hand, RStudio Chief Scientist Hadley Wickham says in his R Packages book:

It's common for packages to be listed in Imports in DESCRIPTION, but not in NAMESPACE. In fact, this is what I recommend: list the package in DESCRIPTION so that it’s installed, then always refer to it explicitly with pkg::fun(). Unless there is a strong reason not to, it's better to be explicit.

With two esteemed R experts giving opposite recommendations, I think it's fair to say that you should pick whichever style suits you best and meets your needs for clarity, efficiency, and maintainability.


If you frequently find yourself using just one function from another package, you can copy the code and add it to your own package. For example, I have a package for personal use that borrows %nin% from the Hmisc package because I think it's a great function, but I don't often use anything else from Hmisc. With roxygen2, it's easy to add @author and @references to properly attribute the code for a borrowed function. Also make sure the package licenses are compatible when doing this.

Include library calls in functions?

As one of the commenters suggest, you should avoid loading packages within a function since

  1. The function now has a global effect - as a general rule, this is something to avoid.
  2. There is a very small performance hit.

The first point is the big one. As with most optimisation, only worry about the second point if it's an issue.

Now that we've established the principle, what are the possible solution.

  1. In small projects, I have a file called packages.R that includes all the library calls I need. This is sourced at the top of my analysis script. BTW, all my functions are in a file call func.R. This workflow was stolen/adapted from a previous SO question

  2. If you're only importing a single function, you could use the :: trick, e.g. package::funcA(...) That way you avoid loading the package.

  3. For larger projects, I create an R package that handles all necessary imports. The benefit of creating a package is detailed in this answer on structuring large R projects.

Is it bad practice to use the system() function when library functions could be used instead? Why?

Unless you are writing code for only one OS, there is no way of knowing if your system call will even work. What happens when there is a system update or an OS upgrade?

Never use a system call if there is a library to do the same function.

Using single functions from a package

Yes, nowadays it should always be safe to call this_pack::this_fn(). If this_pack was not loaded, this will load it (all of it). (Remember that loading and attaching a package are different! Loading it gets it in memory, but not on the search list. Attaching it puts it on the search list.) This may make the first call a little slow, but the package will stay loaded, so subsequent calls will be faster. It used to be the case that evaluating :: took a noticeable amount of time in every call, but I think just-in-time compiling has mostly removed that. But if you want, you can get a local copy using

local_copy <- this_pack::this_fn

and then make calls to local_copy() without paying for the :: lookup again.

Since all packages have namespaces, any calls made by this_pack::this_fn() (or local_copy()) will go to the right place, unless the author of the package tries really hard to subvert the normal mechanisms.

If you are writing a package yourself, you can import just that one function. This will mean that loading your package will trigger a load of this_pack: so your load will be a bit slower, but the first call to this_fn() will be faster.

What are best practices to call different methods based on a variable value in PHP?

Question is a bit general but in most cases using swtich statement or bunch of if-elses is the worst choice because:

  1. After a while it will be really hard to read or/and understand this code.
  2. Those constructions are hard to extend because they often break Dependency Inversion principle.

That's why, depending on the particular case, you can consider using design patterns like:

  1. Factory Method pattern
  2. Bridge pattern
  3. Proxy pattern
  4. ... or something else ;)

EDIT:

In attached code you can consider checking method first (POST, GET, PUT, DELETE etc.) and after this searching for params in exact request type.. But I'm not sure what is purpose of this logic so I can be wrong ;)

is it bad practice to call a function from within an if condition?

There's nothing wrong with it. Though many C functions involve checking the result of parameters rather than the returned value and then you have no other option but to call the function on a line of its own.

Also, this is a common scenario:

result_t result = func();

if(result == ERR1)
...
else if(result == ERR2)
...

Here you can obviously not write

if(func() == ERR1)
...
else if(func() == ERR2)
...

Because then you end up calling the function twice, which is inefficient, but could also give different results.

As for using return from a function as a way to quickly stop executing and go directly to the error handler, it's actually likely the best way of doing so in C. Other alternatives are using messy boolean flags in the loop, or the "on error goto" pattern (which is usually OK but comes with the mandatory, tiresome "goto considered harmful" debate).

As for picking up bad habits: not using const correctness of read-only parameters is a bad habit.



Related Topics



Leave a reply



Submit