# Opinions for exporting common names

**URL:** <https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995>\
**Category:** General Usage\
**Tags:** namespaces\
**Created:** [July 20, 2021, 4:10pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995 "2021-07-20T16:10:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [July 20, 2021, 4:10pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/1 "2021-07-20T16:10:13Z")

</div>

As title says, what are your favourite ways to deal with functions/types which are central to the functionality of a package but for which the best name carry a high risk of collisions? Concrete examples in my case are functions called `name`, `remove!`, `inputs`, `outputs`?

Some options I can think of:

1. Just go ahead an export them anyways
2. Don’t export them but declare them public API in the documentation and recommend that people import them
3. Try to rename them into something less prone to collisions

I suppose 1. is less attractive if there are a lot of other exported functions as it becomes cumbersome to import everything.

I’m also a bit uncertain about the value of exporting things. In my mind it helps a little bit with discovery, but tbh I have never really made use of this myself. I know there is some advice out there to just never use `using` in a module and instead import exactly what is being used or just refer to things by namespace.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 20, 2021, 4:43pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/2 "2021-07-20T16:43:50Z")

</div>

I think (1) is generally fine, since it makes interactive use and exploration of the package easier. If a user wants to use your package and another one with similar exported names, then they’ll have to do `using Foo: bar`, but that’s fine–it’s only as inconvenient as it would already have been if you hadn’t exported those names.

---

<div class="post-metadata">

**Author:** ![ess3sq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ess3sq/32/26834_2.png) [@ess3sq](https://discourse.julialang.org/u/ess3sq)\
**Post date:** [July 20, 2021, 7:24pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/3 "2021-07-20T19:24:04Z")

</div>

1 and 2 are both fine I would think. For 3, it depends. If the functions act on a type defined in your package, export as will because multiple dispatch will take care of it even if there are collisions. If, however, we are considering functions that act on existing types it is reasonable to worry if there might be collisions.

Even if that were the case, though, one can just use the fully qualified function name (as in, with the module name before it) to disambiguate function calls. Such a collision will most likely be noticed by the user, and it is reasonably easy to fix for them.

In general, I guess it makes sense to settle on an exporting policy. Do you want to export all public API functions? Or, for example if you have a framework, do you only export the ‘entry points’? In my opinion it can be quite annoying and verbose for the user to have to specify the module name for everything, and it can be equally annoying to have to import functions explicitly.

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [July 20, 2021, 7:27pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/4 "2021-07-20T19:27:41Z")

</div>

> then they’ll have to do `using Foo: bar`

But won’t they have to change `using Foo` into `using Foo: bar, baz, barbaz, etc.`. Not the worst thing that can happen if one has decent test coverage though.

Then there is also the accidental breakage from when another package adds a conflicting name. I suppose that if one has users it is quickly discovered and fixed.

Perhaps both are non-issues if one does not use `using` in modules to begin with. I think I will try that approach in combination with (1) and see how it goes.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [July 20, 2021, 7:36pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/5 "2021-07-20T19:36:44Z")

</div>

> [@DrChainsaw](#):
>
> 1. Try to rename them into something less prone to collisions

I like this option most. I don’t like when some library takes over names that I wanted to use. For example, AlgebraOfGraphics exports `data`, which is a name I like to use myself.

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [July 20, 2021, 7:37pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/6 "2021-07-20T19:37:41Z")

</div>

> [@ess3sq](#):
>
> If the functions act on a type defined in your package, export as will because multiple dispatch will take care of it even if there are collisions

Hmm, I think that two functions need to be from the same module for this to work. If package `Foo` defines `foo(::Bar)` and package `Foo2` defines `foo(::Baz)` they will collide.

> Such a collision will most likely be noticed by the user, and it is reasonably easy to fix for them.

I guess it is, but it still is a little bit of an annoyance when it causes breakage when a dependency adds a conflicting name. Example is when a package `A` has `using B` and `using C` and a minor release of `C` adds an export of the same name as something `B` already exports. I don’t think users of `A` can fix this (except for using `dev` of course).

I suppose I will try to mitigate this for myself by trying the strategy to only use `import` in the module.

There is still some nagging fear that a package which exports common names becomes that annoying package which you can’t just depend on through `using` but I feel like I’m a bit far into overthinking it territory now 🙂

---

<div class="post-metadata">

**Author:** ![ess3sq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ess3sq/32/26834_2.png) [@ess3sq](https://discourse.julialang.org/u/ess3sq)\
**Post date:** [July 20, 2021, 7:41pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/7 "2021-07-20T19:41:19Z")

</div>

This is not always the case I think. If you implement some data structure, it makes sense to define `size()`, `copy()`, `push!()` etc because it will be easier or more intuitive for people to use. After all, that is kind of the point of multiple dispatch.

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [July 20, 2021, 7:45pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/8 "2021-07-20T19:45:24Z")

</div>

> makes sense to define `size()` , `copy()` , `push!()` etc because it will be easier or more intuitive for people to use.

For functions defined in `Base` this makes perfect sense since pretty much every package depends on `Base`. However, there is no function `Base.data` and therefore they will not be the same function.

I suppose someone could make some lightweigh package called CommonNames.jl which only defines the names, but it does seem fully practical (e.g. what goes in there? how to define the semantics? etc…).

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 20, 2021, 7:46pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/9 "2021-07-20T19:46:15Z")

</div>

> [@DrChainsaw](#):
>
> But won’t they have to change `using Foo` into `using Foo: bar, baz, barbaz, etc.` . Not the worst thing that can happen if one has decent test coverage though.
> 
> Then there is also the accidental breakage from when another package adds a conflicting name. I suppose that if one has users it is quickly discovered and fixed.

Sure, but they’d have to write `using Foo: bar, baz` etc. anyway if you _didn’t_ export, so there’s no extra work.

Also note that conflicting names will never _silently_ break your code in Julia: if `Foo` and `Bar` both export `name`, then:

```julia
using Foo
using Bar
name()

```

will throw a specific error indicating that `name` is ambiguous and must be qualified with `Foo.` or `Bar.`, which is exactly the right thing for a user to do.

This is different than, for example, Python where `from Bar import *` will silently overwrite any names that were previously imported from `Foo`.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 20, 2021, 7:47pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/10 "2021-07-20T19:47:26Z")

</div>

> [@DrChainsaw](#):
>
> how to define the semantics?

Yeah, that’s the right question to ask, and it’s why there is no `CommonNames.jl`. `data` is a nice name, but it doesn’t have enough of a common meaning to be worth sharing in this way.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [July 20, 2021, 7:53pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/11 "2021-07-20T19:53:16Z")

</div>

If I want to use `data` for my own purposes, I can do `import FooPackage: data as foodata`. But this is annoying for me to type and confusing for readers of my code who see `foodata` everywhere. It would be easier for both of us if the original name were something else.

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [July 20, 2021, 7:55pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/12 "2021-07-20T19:55:19Z")

</div>

> Sure, but they’d have to write `using Foo: bar, baz` etc. anyway if you _didn’t_ export, so there’s no extra work.

Sorry for not letting this go, but I feel the dilemma is that `using Foo` would still be perfectly possible if only one just did not export e.g. `name`. E.g. typing `using Foo` followed by `using Foo: name` is less work than typing `using Foo: bar, baz,...`.

It is of course a bit of an ill defined problem to try to classify which names have high collision risk and judge the number of low collision risk names vs the number of high collision risks and I appreciate your advice to just not waste mental capacity on it 🙂

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [July 20, 2021, 7:57pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/13 "2021-07-20T19:57:53Z")

</div>

I don’t think it is an ill-defined problem, and I don’t even think it’s that hard to judge. For example, words that are very short or very common in English/programming have higher collision risk. Of course, it could be quantified further by mining codebases.

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [July 20, 2021, 8:00pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/14 "2021-07-20T20:00:34Z")

</div>

Of course, but you also have to set a threshold, and as @rdeits said, if all your names are below this threshold then not exporting anything is not more useful than exporting everything.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [July 20, 2021, 8:02pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/15 "2021-07-20T20:02:11Z")

</div>

I think `export` is a good way to declare whether a name is public. (Refusing to document nonpublic functions seems bad.)

---

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [July 21, 2021, 8:11am UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/16 "2021-07-21T08:11:17Z")

</div>

I see you perceive the problem that not all common names are in base.

Anyway, all these problems can be solved by loading your packages with `UsingMerge.jl`.

---

<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:** [July 21, 2021, 9:05am UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/17 "2021-07-21T09:05:37Z")

</div>

> [@DrChainsaw](#):
>
> make some lightweigh package called CommonNames.jl which only defines the names

That’s an anti-pattern in Julia unless the names share semantics to a large extent. I definitely don’t want

```julia
close(::GarageDoor)
close(::BankAccount)

```

to be in the same namespace with a common name, that’s like a rake lying in the grass, ready to hit me on the nose.

Personally I think 1 and 2 are fine options, depending on the API and whether it is intended for interactive use or package code. For the latter, `using` everything explicitly is fine and is a good habit.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [July 21, 2021, 11:53am UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/18 "2021-07-21T11:53:51Z")

</div>

I also prefer 1 or 2. I find good names very important for a package’s usability, so better use the “best” name you can find for functions. Also, if you export a name for something the user doesn’t use, they will not notice:

```julia
using DataFrames

# This causes no error although `join` is exported by DataFrames.jl
join = 23

```

Here `join` can be defined by the user because they haven’t previously used the definition from DataFrames.jl. (But that doesn’t help in the case of two packages exporting the same name, and you want to use one of them.)

---

<div class="post-metadata">

**Author:** ![ess3sq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ess3sq/32/26834_2.png) [@ess3sq](https://discourse.julialang.org/u/ess3sq)\
**Post date:** [July 21, 2021, 1:47pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/19 "2021-07-21T13:47:19Z")

</div>

> [@sijo](#):
>
> (But that doesn’t help in the case of two packages exporting the same name, and you want to use one of them.)

Disambiguating by using the module name shouldnt be too difficult though (assuming the user can make sense of the problem).

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [July 21, 2021, 5:42pm UTC](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995/20 "2021-07-21T17:42:16Z")

</div>

> [@Jean\_Michel](#):
>
> I see you perceive the problem that not all common names are in base.
> 
> Anyway, all these problems can be solved by loading your packages with `UsingMerge.jl` .

To the contrary, I lke different functions to be clearly distinguished from each other, either by namespacing or naming.

[Next page](https://discourse.julialang.org/t/opinions-for-exporting-common-names/64995.md?page=2)
