84

Question: What is the difference between using and import in Julia when I'm building my own module?

My guess based on reading the docs: using is used to bring another module into the name-space of the current module. import is used to bring specific types/functions/variables from other modules into the name-space of the current module.

So, how wrong am I?

Colin T Bowers
  • 18,106
  • 8
  • 61
  • 89

3 Answers3

76

The Julia Modules documentation states:

The import keyword [...] only operates on a single name at a time. It does not add modules to be searched the way using does. import also differs from using in that functions must be imported using import to be extended with new methods. [...] Functions whose names are only visible via using cannot be extended.

(Emphasis mine.)

For example, you can use import to add methods to Base.show to pretty-print your own types, but not with using.

There is also importall that imports all exported names of a module.

(This answer refers to Julia 0.6; the documentation was reworded for 1.0.)

smac89
  • 39,374
  • 15
  • 132
  • 179
user4235730
  • 2,559
  • 1
  • 23
  • 36
  • 2
    Very clear thank you (+1+Tick). I actually read that exact passage before asking the question, but clearly didn't decipher the meaning. Your emphasis was very helpful. – Colin T Bowers Nov 24 '14 at 03:11
  • 3
    Could I say `using` is restrictive than `import` since it forbids the name to be extended? Or maybe there is something `using` could do but `import` could not. – Mr.Robot May 10 '19 at 17:35
  • What does the documentation mean when it says "Functions whose names are only visible via `using` cannot be extended"? Specifically, what does "visible" mean in the context of function names? – Leonidas May 18 '21 at 20:58
61

The documentation (updated link for Julia 1.4) about this is excellent. Here's the excerpt which I find to be the most succinct summary:

(a demo module to make the examples below specific)

module MyModule

export x, y

x() = "x"
y() = "y"
p() = "p"

end

(this is a table in the documentation, but StackOverflow still won't add support for tables so... reformatted)

Command

  • using MyModule
    • in-scope: All exported names (x and y), MyModule.x, MyModule.y, and MyModule.p
    • extensible: MyModule.x, MyModule.y, and MyModule.p
  • using MyModule: x, p
    • in-scope: x and p
    • extensible: (nothing)
  • import MyModule
    • in-scope: MyModule.x, MyModule.y, and MyModule.p
    • extensible: MyModule.x, MyModule.y, and MyModule.p
  • import MyModule.x, MyModule.p
    • in-scope: x and p
    • extensible: x and p
  • import MyModule: x, p
    • in-scope: x and p
    • extensible: x and p
Ron Wolf
  • 103
  • 4
Nathan
  • 9,651
  • 4
  • 45
  • 65
6

A summary of the main difference, in a way that I find easy to remember:

  1. using NiceStuff allows usage access to exported names without the module qualifier, which import NiceStuff doesn't; and
  2. import NiceStuff: nice allows extension access (adding methods) to the specified function without the module qualifier, which using NiceStuff: nice doesn't.

And a minor difference:
X as Y syntax is allowed for individual identifiers with both using and import (using Random: randstring as rstr, import Random: randstring as rstr) but for the module name itself, import Random as Rnd is allowed while using Random as Rnd is an error.

Some other points I found useful from the Modules docs page

using ModuleName is the only form for which export lists matter at all.

import NiceStuff is equivalent to using NiceStuff: NiceStuff.

Sundar R
  • 13,776
  • 6
  • 49
  • 76