Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

recommend explicit using Foo: Foo, ... in package code (was: "using considered harmful") #42080

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
9 changes: 9 additions & 0 deletions base/docs/basedocs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ kw"help", kw"Julia", kw"julia", kw""
available for direct use. Names can also be used via dot syntax (e.g. `Foo.foo` to access
the name `foo`), whether they are `export`ed or not.
See the [manual section about modules](@ref modules) for details.

!!! note
Doing `using Foo` in packages or code that you want to keep working with
updated dependencies is not recommended. The reason for this is if another
dependency starts to export one of the same names as `Foo` the code will
error due to an ambiguity in which package the name should be taken from.
Instead, explicitly list what names you want to use from Foo, for example:
`using Foo: Foo, parsefile, readfile` to get access bring `Foo` and two
functions `parsefile` and `readfile` into scope.
IanButterworth marked this conversation as resolved.
Show resolved Hide resolved
mbauman marked this conversation as resolved.
Show resolved Hide resolved
mbauman marked this conversation as resolved.
Show resolved Hide resolved
"""
kw"using"

Expand Down
22 changes: 21 additions & 1 deletion doc/src/manual/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ and above. To maintain compatibility with Julia 1.10 and below, use the `@compat

### Standalone `using` and `import`

Possibly the most common way of loading a module is `using ModuleName`. This [loads](@ref
For interactive use, the most common way of loading a module is `using ModuleName`. This [loads](@ref
code-loading) the code associated with `ModuleName`, and brings

1. the module name
Expand Down Expand Up @@ -168,6 +168,26 @@ Importantly, the module name `NiceStuff` will *not* be in the namespace. If you
julia> using .NiceStuff: nice, DOG, NiceStuff
```

!!! note
Qualifying the names being used as in `using Foo: Foo, f` is
recommended over plain `using Foo` for released packages, and other
code which is meant to be re-used in the future with updated dependencies
or future versions of julia.

The reason for this is if another dependency starts to export one of the
same names as `Foo` and you attempt to use that name, then previously working
code will error due to an ambiguity in which package the name should be
taken from. This is especially problematic in released packages which needs
to be forward-compatible with the future releases.

For example, if your package has dependencies `Foo` version `1` and `Bar`
version `2`, and you write `using Foo, Bar` the current versions may not
have any conflicting names, but if in a minor non-breaking release of `Bar`
version 2.x it also exports the name `f`, then suddenly calling the function
`f` will error because the name has become ambiguous. This issue can be
avoided by explicitly listing what names you want to use from which modules.


Julia has two forms for seemingly the same thing because only `import ModuleName: f` allows adding methods to `f`
*without a module path*.
That is to say, the following example will give an error:
Expand Down