When is it necessary to qualify names

I am having trouble figuring out when I need to qualify names or use modules and when I don’t.

  1. * seems to do matrix multiplication even though I haven’t even issued using LinearAlgebra.
  2. optimize worked after using Optim but I needed Optim.minimizer to get that value out of the result. Admittedly the latter was in a slightly different environment, namely a juno session with namespace set to the module in which Optim was used.
  3. I needed Iterators.product to use product. I did this even though I had no using Iterators directive. And I also did not need Base.Iterators.product, which I gather is the full name.

My understanding is that in principle I can use exported names unqualified after using the module that exports them, and other names in the module with qualification. But the documentation I’ve looked at doesn’t seem to flag the distinction when discussing different functions.

More hazily, I think Base and some other modules are always available (unless I take special steps) and so I can access its members easily. This may explain why Iterators rather than Base.Iterators is sufficient.

1 Like

This is a very good question; one that should benefit many. Thank you for asking.

When Julia starts interactively, one sees the prompt julia > … many functions are available immediately just by typing their names. How many? Which functions? click on this to see that

Many more functions and organized capabilities are available and at hand for use.
Here starts the use of qualified names. Base itself has submodules. The submodules contain functions. To use one of those functions, use the submodule name to qualify the function name. click on this link to see the submodules

Next are functions from members of the standard library. To use these, you have to use them like this: using LinearAlgebra. They are in the docs, from Base64 to Unicode, includINT: Pkg, Dates, Statistics, LinearAlgebra, Random.

Beyond that are the packages of our ecosystem.

2 Likes

Yes. When you type using A, two quite distinct things happen:

  • The code from A is loaded into the runtime. This may add new methods to existing functions.
  • The export list from A is made available as names (bindings) in the current module.

Because the function * comes from Base you already have access to that name, so the name import part of using LinearAlgebra is irrelevant to whether * can multiply matrices. Instead, it depends on whether the code from LinearAlgebra is loaded. In the default setup this code is always loaded because LinearAlgebra is a standard library.

2 Likes