# When to use \`using Package: function\` and when to use \`import Package: function\`

**URL:** <https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091>\
**Category:** General Usage\
**Created:** [June 2, 2024, 9:50pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091 "2024-06-02T21:50:06Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [June 2, 2024, 9:50pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/1 "2024-06-02T21:50:06Z")

</div>

I have a package, which imports a couple of package, as well as a couple of extra functions from these. I am trying to figure out whether there is some “rule” for whether to use

```julia
using Package: function

```

or

```julia
import Package: function

```

From looking around, my impression is that I should use `import Package: function` if I want to overload `function` (i.e. create a dispatch for some structure that my package creates). If I only intend to use the function, I should instead use ` using Package: function`.

Is this correct?

---

<div class="post-metadata">

**Author:** ![Satvik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/satvik/32/20486_2.png) [@Satvik](https://discourse.julialang.org/u/Satvik)\
**Post date:** [June 2, 2024, 10:45pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/2 "2024-06-02T22:45:11Z")

</div>

I believe you need to use import to extend an existing function, and using does not work:

```julia
struct MyType
  a::Int
end

using Base: +

(+)(x::MyType, y::MyType) = MyType(x.a + y.a)

ERROR: invalid method definition in Main: function Base.+ must be explicitly imported to be extended
Stacktrace:
 [1] top-level scope
   @ none:0
 [2] top-level scope
   @ REPL[20]:1

import Base: +
(+)(x::MyType, y::MyType) = MyType(x.a + y.a)
+ (generic function with 208 methods)

MyType(1) + MyType(2)
> MyType(3)

```

Though you can also use the full name without importing:

```julia

function Base.:+(x::MyType, y::MyType)
  return MyType(x.a + y.a)
end

MyType(1) + MyType(2)
> MyType(3)

```

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [June 2, 2024, 10:55pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/3 "2024-06-02T22:55:10Z")

</div>

Got it, and if I do not plan on extending, there is no reason to use `import` instead of `using`?

I am trying to figure out which to use in my package, and if this is the only difference I’d rather stick to `using package: function` for those I do not plan on extending (also a nice way to mark which functions I plan to do what with)

---

<div class="post-metadata">

**Author:** ![Satvik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/satvik/32/20486_2.png) [@Satvik](https://discourse.julialang.org/u/Satvik)\
**Post date:** [June 2, 2024, 10:57pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/4 "2024-06-02T22:57:45Z")

</div>

As far as I can tell, the other user facing functionality is exactly the same between `using Statistics: cor` and `import Statistics: cor`. So yes, it’s a nice way to denote which ones you plan to extend.

There’s also a minor issue where there used to a bug where `using Statistics: cor` would cause `cor` not to tab-complete properly in the REPL, while `import Statistics: cor` would. But I think that was fixed recently.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [June 2, 2024, 11:33pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/5 "2024-06-02T23:33:26Z")

</div>

I tend to avoid `import Package: function` and just extend via the following syntax.

```julia
function Package.function(args...)
   # code here
end

```

---

<div class="post-metadata">

**Author:** ![savq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/savq/32/22063_2.png) [@savq](https://discourse.julialang.org/u/savq)\
**Post date:** [June 2, 2024, 11:39pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/6 "2024-06-02T23:39:18Z")

</div>

Never use `import`.

- If you don’t want to extend a method, `using Package: f` is enough.
- If you want to extend a method, you should do it explicitly, so `using` is still better.
- If you want to bring a module into scope without any of its exports, then write `using Package: Package`.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [June 3, 2024, 4:46am UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/7 "2024-06-03T04:46:28Z")

</div>

A nice way to have such decisions made for you is to use a style guide and the associated JuliaFormatter.jl config. I usually stick to the [BlueStyle](https://github.com/JuliaDiff/BlueStyle), which pretty much says

> [@savq](#):
>
> Never use `import`.

Note that ExplicitImports.jl can now help you track down lonely `using MyPackage` statements and replace them.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [June 3, 2024, 6:04am UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/8 "2024-06-03T06:04:22Z")

</div>

> [@savq](#):
>
> using Package: Package

I really would like that to be

```julia
using Package: .

```

> **[Shortcut for \`using X: X, ...\` · JuliaLang/julia · Discussion #52380](https://github.com/JuliaLang/julia/discussions/52380)**
>
> In code for a library with many dependencies, it is advantageous to explicitly declare from where all symbols are being added to the local namespace. This helps to avoid ambiguity issues when multi...

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [June 3, 2024, 8:24am UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/9 "2024-06-03T08:24:20Z")

</div>

> [@savq](#):
>
> If you don’t want to extend a method, `using Package: f` is enough.

Full agree.

> [@](#):
>
> If you want to extend a method, you should do it explicitly, so `using` is still better.

Mostly agreed, but it’s not a clear cut win when the package name is very long, and it doesn’t work for macros.

> [@savq](#):
>
> If you want to bring a module into scope without any of its exports, then write `using Package: Package`.

No way! I’m not going to repeat myself just because an opinionated style guide thinks `import` is evil. (I would be happy to `using MyPackage: .` though if that was implemented.)

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 3, 2024, 9:50am UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/10 "2024-06-03T09:50:56Z")

</div>

The reason why `import Blah: foo` is usually discouraged is that forcing qualification gives you added protection, albeit at runtime, from silently mixing up two same names intended to be from different modules. Consider one scenario where you start writing some other `include`d file down the line and you forgot you imported `foo` way back, so you start making a bunch of methods for what you think is a new function `foo` to do something else. At runtime, those methods are added to the imported function `foo` instead, easily breaking `Blah` by replacing methods or affecting dispatch.

Of course the reasonable counterargument is that you should keep all your imports in one place and check the names there regularly to avoid accidental name reuse. After all, variable accesses and function calls aren’t often qualified, so you’ll have to check the list anyway to distinguish the module’s names from the imports. This incidentally is why I never bought the other argument that qualification is important for distinguishing imports at first glance; if it were so important we’d be qualifying everything like in Python.

Now consider the _reverse_ scenario where you decide to import a new package’s function `import Blah: foo` at the start but you forgot you had already made an internal function `foo` somewhere in a buried `include`d file. Now you’ll have to check ALL names in ALL files to avoid name reuse. A linter could do this automatically, but it’s nice if the base language also warns or stops you at runtime before anything starts running for days. This runtime protection is already there for reassignment, even for `import`, so it’s nice if that were consistent for adding methods:

```julia
julia> module A; x = 1; foo() = 0 end
Main.A

julia> import .A: x, foo

julia> x = 2
ERROR: cannot assign a value to imported variable Main.x
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

julia> A.x = 2 # reassignment needs qualifying
2

julia> foo(x) = 1 # adding method does not need qualifying
foo (generic function with 2 methods)

```

That’s not to say `import Blah: foo` should never be used. A small enough module won’t span enough files to run into such issues, and base Julia does `import Base: ____ ` a lot because those symbols are more readily recognized anyway. Macros don’t have many argument types worth dispatching over, but when they do, module qualification currently does not work so you need [`import Blah: @foo`](https://discourse.julialang.org/t/how-to-define-a-macro-via-package-extension/114218/4). That’s not so bad though because extending macros from other packages is type piracy and should be avoided.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [June 3, 2024, 9:58am UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/11 "2024-06-03T09:58:08Z")

</div>

> [@Benny](#):
>
> Macros don’t have many argument types worth dispatching over

Worth noting here is that package extensions have added the pattern of defining an empty macro in the base package and extending it with a method in the extension module.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 3, 2024, 10:05am UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/12 "2024-06-03T10:05:17Z")

</div>

I’m not a fan of functions or macros that do nothing until a separate package is imported, but it’s definitely a lot more maintainable for the names to unconditionally exist and belong to 1 package rather than try to make them show up only when an extension is loaded.

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [June 3, 2024, 1:16pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/13 "2024-06-03T13:16:31Z")

</div>

Everyone, this is amazing ❤. Thanks a lot, this is really useful to learn how these things work 🙂

---

<div class="post-metadata">

**Author:** ![sbuercklin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sbuercklin/32/15728_2.png) [@sbuercklin](https://discourse.julialang.org/u/sbuercklin)\
**Post date:** [June 3, 2024, 1:26pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/14 "2024-06-03T13:26:51Z")

</div>

> [@GunnarFarneback](#):
>
> Mostly agreed, but it’s not a clear cut win when the package name is very long

The `import X as Y` syntax is very helpful for this:

```julia
julia> import Base as B

julia> B.length((1,2,3))
3

```

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [June 3, 2024, 1:28pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/15 "2024-06-03T13:28:30Z")

</div>

Absolutely, unless your goal is not to use `import`. 🙂

---

<div class="post-metadata">

**Author:** ![sbuercklin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sbuercklin/32/15728_2.png) [@sbuercklin](https://discourse.julialang.org/u/sbuercklin)\
**Post date:** [June 3, 2024, 1:30pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/16 "2024-06-03T13:30:18Z")

</div>

Is there any semantic difference between `using Base: Base; const B = Base` and `import Base as B`? It seems like splitting hairs to argue that this is a bad use of `import`, but I also would’ve preferred `using Base as B` for this

E- ah, there is `using Base: Base as B` if we want to duck `import` usage

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [June 3, 2024, 1:33pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/17 "2024-06-03T13:33:17Z")

</div>

No practical difference for `Base`, but in general `import X as Y` doesn’t bring `X` into your namespace, which may matter for name collisions.

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [June 3, 2024, 1:44pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/18 "2024-06-03T13:44:06Z")

</div>

Wait, this is useful. I do use

```julia
using Package
const Pk = Package

```

but changing that to either of

```julia
import Package as Pk
using Package: Package as Pk 

```

might make sense?

---

<div class="post-metadata">

**Author:** ![savq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/savq/32/22063_2.png) [@savq](https://discourse.julialang.org/u/savq)\
**Post date:** [June 3, 2024, 5:40pm UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/19 "2024-06-03T17:40:58Z")

</div>

Yes. It’s better to alias the package with `as`. If you write

```julia
using Package
const Pk = Package

```

Then you bring `Package` and its exports into scope.

However, If you write

```julia
using Package: Package as Pk 

```

You only bring `Pk` into scope.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 4, 2024, 5:51am UTC](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091/20 "2024-06-04T05:51:10Z")

</div>

> [@savq](#):
>
> It’s better to alias the package with `as`.

A new variable is also [semantically different](https://discourse.julialang.org/t/rename-just-one-of-imported-names-with-using/105026/13) from an imported and possibly renamed variable, though not practically if `const`.

A possible reason for why the import system is so complicated is that renaming wasn’t present for all of v1 (looking it up it seems to be 1.7, was it really that late?). With renames to a couple characters, even qualifying imported modules at accesses and function calls is pretty smooth in practice. I’d still rather import the names to occupy the name in the module and stop assignments of a new one, and might as well use it without qualification sometimes at that point.

[Next page](https://discourse.julialang.org/t/when-to-use-using-package-function-and-when-to-use-import-package-function/115091.md?page=2)
