# Is an explicit "export" a good thing?

**URL:** <https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446>\
**Category:** General Usage\
**Created:** [December 1, 2017, 9:31pm UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446 "2017-12-01T21:31:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 1, 2017, 9:31pm UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/1 "2017-12-01T21:31:49Z")

</div>

I am beginning to have doubts about the wisdom of using “export” in modules. When the modules get "using"ed (could we change this keyword please to “use” instead of “using”?), for someone coming to a finished code it may be an unnecessary cognitive burden to figure out the origin of the functions coming from these modules. On the other hand, if the writer says explicitly

```julia
using MyMod: fun

```

the comprehension of the code is enhanced and no searching is required.

I wonder if someone wants to put a word either for or against “export”?

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [December 1, 2017, 10:10pm UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/2 "2017-12-01T22:10:40Z")

</div>

This doesn’t work with multiple methods. E.g. I can extend `Base.push!` for my type, never export it, but it will be automatically available for a user once he imports my module.

On the other hand, `methods(push!)` and `@which push!(obj, x)` always works and doesn’t depend on `export`.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [December 1, 2017, 10:13pm UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/3 "2017-12-01T22:13:32Z")

</div>

I’m also a bit on the fence on this topic. The danger of name clashes due to exports with the same name from different packages is always in the back of my mind. Packages like `ForwardDiff` don’t export anything, probably for this reason (it is likely that some other package could also export e.g. `jacobian` and `derivative`).

On the other hand, I, and I think many others currently implicitly treat the list of exported symbols as the ‘official’ API of a package, with anything that’s not exported subject to change without deprecation.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 1, 2017, 11:14pm UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/4 "2017-12-01T23:14:53Z")

</div>

The API point is a good one. I would probably keep a list of “exported” functions in a comment at the top of documentation as the API spec.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 1, 2017, 11:23pm UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/5 "2017-12-01T23:23:50Z")

</div>

It depends on what you’re doing. In a package, being explicit is usually better. In the REPL prototyping for a class, having to always be explicit is slow and annoying.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 1, 2017, 11:47pm UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/6 "2017-12-01T23:47:19Z")

</div>

Good point. But the problem is that once the developer writes “export blah, blahblah”, the cat is out of the bag.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 2, 2017, 12:19am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/7 "2017-12-02T00:19:35Z")

</div>

> [@PetrKryslUCSD](#):
>
> But the problem is that once the developer writes “export blah, blahblah”, the cat is out of the bag.

No, just use `import`

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 2, 2017, 1:30am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/8 "2017-12-02T01:30:41Z")

</div>

Could you explain what you mean?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [December 2, 2017, 1:36am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/9 "2017-12-02T01:36:06Z")

</div>

`import` will not bring the symbols `export`ed by the package into the namespace. It will only bring the package name itself so you need to qualify with `PackageName.symbol`. One thing that I find a bit unfortunate is that there isn’t really any way to denote `symbol` as public if it is non exported. You can, as an author, work around this by something like:

```julia
module Package
   public_function(x) = x
   public_function2(x) = __Inner.f(x)

    module __Inner
        f(x) = x
        other_private(x) = x
        more_private(x) = x
    end
end

```

Everything in `Package.` namespace is now public (except `__Inner`).

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [December 2, 2017, 1:43am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/10 "2017-12-02T01:43:48Z")

</div>

> [@kristoffer.carlsson](#):
>
> It will only bring the package name itself so you need to qualify with PackageName.symbol

Or you can import only symbols you want:

```julia
import PackageName: symbol1, symbol2

```

which should act exactly as `using MyMod: fun` for not exported functions as mentioned in the first post.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 2, 2017, 2:01am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/11 "2017-12-02T02:01:19Z")

</div>

But one can do

```julia
using Mod: fun

```

to get to call `fun(x)` as if it was exported? No?

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 2, 2017, 2:05am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/12 "2017-12-02T02:05:55Z")

</div>

Btw I am not so much concerned w/ public vs private. In my (barely formed) view it seems counterproductive for READERS of code to have to figure out where functions came from after they were exported from modules and now appear in the code as if by magic.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [December 2, 2017, 2:08am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/13 "2017-12-02T02:08:13Z")

</div>

Yes, so use `import` then and use the module prefix att call sites.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 2, 2017, 2:10am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/14 "2017-12-02T02:10:42Z")

</div>

Isn’t it “nicer” to use `using Mod: f; f(x)` rather than `import Mod; Mod.f(x)`? Just curious why you recommend import…

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 2, 2017, 5:14am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/15 "2017-12-02T05:14:22Z")

</div>

@kristoffer.carlsson, @ChrisRackauckas, @tkoolen Could one eat the cake and have it too?

Look Ma, no exports!

```julia
module mmm
function test()
    println("in test()")
end
function folly()
    println("in folly()")
end
end

```

Hence to use these functions one must qualify them or bring them in explicitly.

```julia
julia> include("mmm.jl")
mmm

julia> mmm.folly()
in folly()

julia> using mmm: folly

julia> folly()
in folly()

```

And here is the explicit API:

```julia
module mmm_API
using mmm: test, folly
export test, folly
end

```

which is used as

```julia
julia> include("mmm_API.jl")
mmm_API

julia> using mmm_API

julia> folly()
in folly()

```

So if you are inclined to make it real clear where the functions are coming from, use `mmm`; otherwise use the API module.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 2, 2017, 5:22am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/16 "2017-12-02T05:22:58Z")

</div>

Or if you just did what I noted earlier, you’d get all of that with less work. `using` exported names into the namespace. `import` doesn’t. Problem solved without an extra module, and it’s consistent across all of Julia.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [December 2, 2017, 5:35am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/17 "2017-12-02T05:35:50Z")

</div>

I am sorry. I need a bit more clarity. What exactly ARE you saying?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 2, 2017, 5:36am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/18 "2017-12-02T05:36:58Z")

</div>

`import mmm_API` is the same as `using mmm`, so making the two modules is unnecessary since there’s already a way to turn off exporting if you don’t want it.

---

<div class="post-metadata">

**Author:** ![bicycle1885](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bicycle1885/32/107_2.png) [@bicycle1885](https://discourse.julialang.org/u/bicycle1885)\
**Post date:** [December 2, 2017, 6:01am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/19 "2017-12-02T06:01:35Z")

</div>

Importing exported functions with `using` is sometimes useful, especially for interactive environments (e.g. Jupyter, RPEL) and for development. So, I’d say 👍 to use `export` in some modules.

What I dislike is using `using` in source code because it hides the origin of names used in the code. In such a case, we can always use `import` and explicitly prefix names with the module name, or, explicitly `import` names from the module if those names are frequently used in the code.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 2, 2017, 7:06am UTC](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446/20 "2017-12-02T07:06:25Z")

</div>

The current usage of `export` has two (related) roles:

1. a shorthand for documenting the API (“this is exported so you should read its documentation, this isn’t so think before you use it”),

2. quickly importing a consistent set of nouns and verbs that was determined by the package authors to be useful, with various trade-offs in mind (eg conflicts with other packages).

There is no consistent standard, so the package authors rely on tradition, example, and their own preferences about what to export.

I think that writing good documentation _and_ a consistent API with a few symbols that need to be `import`ed explicitly makes no explicit `export`s viable. Some packages indeed do this; [AD](http://www.juliadiff.org/) is a good example.

OTOH, some packages (and collections of packages) cultivate a consistent API that is exported, and make sure that there are no conflicts; sometimes with the use of packages with the sole purpose of defining and exporting some skeleton of a generic interface. [JuliaStats](https://github.com/JuliaStats) is an example of this.

I think that the point you are making is valid. On the other hand, some languages treat their namespaces differently, eg in `R` the whole API is imported by default for libraries, so most users don’t even need to think about namespaces. For users coming from these languages, starting everything with a set of `import`s may be unusual, especially in interactive use.

[Next page](https://discourse.julialang.org/t/is-an-explicit-export-a-good-thing/7446.md?page=2)
