# "Names" packages?

**URL:** https://discourse.julialang.org/t/names-packages/58981
**Category:** Tooling
**Created:** [April 10, 2021, 2:00pm UTC](https://discourse.julialang.org/t/names-packages/58981 "2021-04-10T14:00:56Z")
**Posts on this page:** 12
**Page:** 2

<div class="post-metadata">

### Author: ![cscherrer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cscherrer/32/7631_2.png) [@cscherrer](https://discourse.julialang.org/u/cscherrer)
#### Post date: [April 13, 2021, 3:09pm UTC](https://discourse.julialang.org/t/names-packages/58981/21 "2021-04-13T15:09:42Z")

</div>

> [@Tamas\_Papp](#):
>
> This is not a problem, it is a _feature_ that protects the user/programmer. The two names denote different things, and should not be automatically conflated. See this epic thread:

This is very different from what I’m describing. I’m suggesting a collection of names to be used in the context of a specific domain, with the agreement that type piracy should be avoided. It should always be opt-in, never automatic.

---

<div class="post-metadata">

### Author: ![cpfiffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cpfiffer/32/208747_2.png) [@cpfiffer](https://discourse.julialang.org/u/cpfiffer)
#### Post date: [April 13, 2021, 3:30pm UTC](https://discourse.julialang.org/t/names-packages/58981/22 "2021-04-13T15:30:50Z")

</div>

> [@cscherrer](#):
>
> With apologies to @cpfiffer and @devmotion, here’s an example from [AbstractMCMC.jl](https://github.com/TuringLang/AbstractMCMC.jl):

🤣

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [April 13, 2021, 4:20pm UTC](https://discourse.julialang.org/t/names-packages/58981/23 "2021-04-13T16:20:49Z")

</div>

> [@cscherrer](#):
>
> Some packages are designed to be used interactively by “end users”. I’d like to make things easy for them - the should be able to say `using Foo` and have things just work.

I understand your case, and sometimes to avoid this kind of problem you simply extend a function that already exists (specially if it is from `Base`), to avoid such name clashes. This happened to JuMP in a [PR](https://github.com/jump-dev/JuMP.jl/pull/2198) I did for JuMP. [mlubin questioned the choice](https://github.com/jump-dev/JuMP.jl/pull/2198#issuecomment-598171014) of extending `Base.empty!` instead creating a `JuMP.empty!` but [I warned this](https://github.com/jump-dev/JuMP.jl/pull/2198#issuecomment-598187780) would make us need to rewrite every `empty!` on `JuMP` code to qualify if it was the `Base` one or the `JuMP` one, and it would make it a headache for most JuMP users that simple do `using JuMP` and create scripts with models (i.e., are not package mainteners). In the end, we extended `Base.empty!` ([I had also some more specific and convincing arguments](https://github.com/jump-dev/JuMP.jl/pull/2198#issuecomment-598539875)).

---

<div class="post-metadata">

### Author: ![cscherrer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cscherrer/32/7631_2.png) [@cscherrer](https://discourse.julialang.org/u/cscherrer)
#### Post date: [April 13, 2021, 4:47pm UTC](https://discourse.julialang.org/t/names-packages/58981/24 "2021-04-13T16:47:37Z")

</div>

Great example, thanks!

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [April 13, 2021, 6:07pm UTC](https://discourse.julialang.org/t/names-packages/58981/25 "2021-04-13T18:07:37Z")

</div>

> [@Henrique\_Becker](#):
>
> [mlubin questioned the choice](https://github.com/jump-dev/JuMP.jl/pull/2198#issuecomment-598171014) of extending `Base.empty!` instead creating a `JuMP.empty!`

I probably would have voted for using the name `reset!` or `reset_model!` instead of extending `Base.empty!`. The concept of resetting a JuMP model, although similar to the idea of emptying a collection, is a bit separate and should therefore have a different name.

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [April 13, 2021, 6:12pm UTC](https://discourse.julialang.org/t/names-packages/58981/26 "2021-04-13T18:12:32Z")

</div>

> [@CameronBieganek](#):
>
> I probably would have voted for using the name `reset!` or `reset_model!` instead of extending `Base.empty!`

This brings up a related issue that I don’t think has been discussed yet – discoverability. If you make a new name for your function in order to prevent name collisions, users need to be able to figure out what that is. Users familiar with something like `empty!` or `sample` will likely try to use it, get errors, then type `? empty!` which will not help them unless `reset!` starts showing up in suggested similar functions. Maybe this is possible?

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [April 13, 2021, 6:23pm UTC](https://discourse.julialang.org/t/names-packages/58981/27 "2021-04-13T18:23:31Z")

</div>

We do have a problem in Base where certain very generic words have been claimed for functions which are not very generic. For example:

```julia
help?> reset

  reset(s)

  Reset a stream s to a previously marked position, and remove the
mark. Return the previously marked position. Throw an error if the
stream is not marked.

```

```julia
help?> step

  step(r)

  Get the step size of an AbstractRange object.

```

`step` should probably be called `stepsize`. It’s more specific to what the function actually means. Additionally, `stepsize` is clearly a noun rather than a verb (`step` could be either), which indicates that you’re dealing with an accessor function.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [April 13, 2021, 6:58pm UTC](https://discourse.julialang.org/t/names-packages/58981/28 "2021-04-13T18:58:27Z")

</div>

> [@CameronBieganek](#):
>
> The concept of resetting a JuMP model, although similar to the idea of emptying a collection, is a bit separate and should therefore have a different name.

Note that `Gurobi.jl` and `CPLEX.jl` did not implement `Base.empty!` but instead `MOI.empty!` that is the “fallback” of `Base.empty!(::ModelLike)` and they also implemented `MOI.is_empty` (basically MOI version of `Base.isempty` but I think there is no `Base.isempty(::ModelLike)`) both functions are used internally so the concept of a Model of _some kind of container_ seems useful/adequate.

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [April 13, 2021, 7:08pm UTC](https://discourse.julialang.org/t/names-packages/58981/29 "2021-04-13T19:08:08Z")

</div>

> [@Henrique\_Becker](#):
>
> the concept of a Model of _some kind of container_ seems useful/adequate.

Yeah, I don’t mean to say that it is necessarily wrong, but it is a slippery slope. Just about any struct could be thought of as a container, especially if one is thinking at the more mechanical implementation level.

---

<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: [April 13, 2021, 7:09pm UTC](https://discourse.julialang.org/t/names-packages/58981/30 "2021-04-13T19:09:58Z")

</div>

> [@cscherrer](#):
>
> Luckily, I’m not bound to that API; I can instead define

I think we’re in agreement that you shouldn’t be locked into using an API you don’t like. My only difference is on reusing the old function for your new API.

It’s true that

```julia
julia> rand!() = 1
rand! (generic function with 1 method)

julia> using Random
WARNING: using Random.rand! in module Main conflicts with an existing identifier.

```

can be frustrating to users, especially new ones. I think the experience can be improved significantly. In particular:

1. “identifier” is compiler terminology, not user terminology
2. What are the types and docs of the existing object and the new object
3. Where are they each defined in this file and originally?
4. What does it mean that they “conflict”? What is Julia doing about that? What does the name mean now?
5. What can I do to avoid this problem?

> [@cscherrer](#):
>
> In this case I used my own `sample` , but there would be no problem using the one from StatsBase, at least not that I can see.
> 
> And again, the problem I’m trying to solve isn’t really a problem for me, but for the end user. I’d like to avoid the situation where using packages together suddenly changes what’s easily available in help (" `?sample` ") or `methods` , which can be especially confusing for beginners.

There are problems for the end user.

1. (All users) The help is hard to read. `?sample` grows really long and confusing. I’m disoriented and I don’t understand the semantics of the functions I’m using.
2. (All users) Nonetheless, I try to be a good developer and follow the rules, so I read the web docs of `AbstractMCMC` and try to call `AbstractMCMC.sample` on my `CScherrer.Chain`, and I pass it `chain_type=` as documented, and it gives me a confusing error that `sample` has no `chain_type` parameter.
3. (Advanced users) It breaks the automatic “it just works” magic of Julia’s interoperability: the ability to mix functions from one package with types from another. Suppose I actually want the semantics of `AbstractMCMC.sample` because I like how it handles errors (or logging, or missing data, or whatever), together with `CScherrer.Chain`. Now I can’t just use that function even if they’re compatible, because it will automatically dispatch to the semantically wrong function and I won’t get the behavior I wanted unless I explicitly choose `sample{AbstractMCMC.MCMCChain}(cscherrer_chain)`, sacrificing automatic interoperability (in the sense above), one of Julia’s best features.

---

<div class="post-metadata">

### Author: ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)
#### Post date: [April 13, 2021, 7:18pm UTC](https://discourse.julialang.org/t/names-packages/58981/31 "2021-04-13T19:18:33Z")

</div>

Well, slippery slopes are often the fallacious type. I would say that a large amount of Julia types are just `immutable` `isbits` `struct`s and those very clearly cannot be considered containers.

A JuMP Model:

- Often starts with no variables and constraints, unless they are explicitly given or it is loaded from somewhere.
- Has a good part of its interface dedicated to adding and removing variables/constraints from the Model object.
- The variables and constraints may be registered by name (if not anonymous) `model[:variable_or_constraint_name]` and if they are not, they can always at least be referred by an index that is given back by the object.
- The own internal code cares about if there is something inside it (`MOI.is_empty`) and sometimes `empty!` it to execute another action.

It can be a swan but at most distances it passes for a duck.

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [April 13, 2021, 7:25pm UTC](https://discourse.julialang.org/t/names-packages/58981/32 "2021-04-13T19:25:03Z")

</div>

Yeah, I should have said mutable structs.

It’s not really spelled out in the manual, but I would say that `Base.length` is the most essential method that should be defined for a collection. Since `JuMP.Model` doesn’t have a `length` method, it seems like a stretch to call it a collection.

> [@Henrique\_Becker](#):
>
> The variables and constraints may be registered by name (if not anonymous) `model[:variable_or_constraint_name]` and if they are not, they can always at least be referred by an index that is given back by the object.

Indexability does not necessarily imply that a type is a collection:

```julia
struct A
    x
    y
end

Base.getindex(a::A, sym) = getproperty(a, sym)

```

Anyhow, this is starting to diverge from the main topic of the thread…

[Previous page](https://discourse.julialang.org/t/names-packages/58981.md?page=1)
