# "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:** 20\
**Page:** 1

<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 10, 2021, 2:00pm UTC](https://discourse.julialang.org/t/names-packages/58981/1 "2021-04-10T14:00:56Z")

</div>

The issue in this post has come up a few times in different contexts:

> [@Stheno marginals](https://discourse.julialang.org/t/stheno-marginals/58943):
>
> I’m trying to follow the examples but having some issues. What’s going wrong here? [8188c328] Stheno v0.7.1 # # This file just shows how some of the basic manipulations you can do in Stheno work in # practice. See the main documentation and the rest of this examples folder for more info. # # Set up the environment to run this example. Make sure you're within the folder that this # file lives in. # The time-to-first-plot issue means that this might take a little while. using LinearAlgebra, R…

Julia’s multiple dispatch is very convenient for users, but the “who owns this name” issue can be awkward for package developers.

This is common enough that I wonder if we should have collections of “namespace packages”. For example, `JuliaStats` could have a `StatsNames.jl` that would “own” lots of stats-related names, and have no functionality beyond this. This could be a common and very lightweight dependency.

The potential benefits are pretty clear, but I can see a few potential problems:

1. Methods on `Base` types would constitute type piracy
2. We’d have to come to an agreement about the high-level semantics of various functions and reasonable return types. It would be important for this to be sensible without being overly restrictive.
3. Even a small degree of bureaucracy has the potential to discourage new developers and slow growth of the ecosystem
4. Many function names are already tied to existing packages. If these have methods for types those packages don’t own, it could be difficult to extricate them.

Related to this last point, many names correspond to structs, and I think it’s safe to assume we’d need to leave those alone.

Anyway… If this worked out, the end result could be very nice - an ecosystem with a consistent “look and feel”. I can see some tradeoffs, but some of it’s not very clear to me yet.

What do you think? Is this a good approach? Is there a better way to approach this problem?

---

<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:** [April 10, 2021, 2:03pm UTC](https://discourse.julialang.org/t/names-packages/58981/2 "2021-04-10T14:03:10Z")

</div>

We already have one for CommonSolve.jl. I think some others could be needed. Making sure to avoid ambiguities is the real issue.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [April 10, 2021, 2:14pm UTC](https://discourse.julialang.org/t/names-packages/58981/3 "2021-04-10T14:14:45Z")

</div>

I think [GitHub - JuliaData/DataAPI.jl: A data-focused namespace for packages to share functions](https://github.com/JuliaData/DataAPI.jl) is a good example of this, with some good patterns to borrow, e.g. every function has a single “owner” who is allowed to define generic fallbacks / methods for Base types; everyone else can extend it but cannot pirate (to avoid clashes).

---

<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 11, 2021, 1:11am UTC](https://discourse.julialang.org/t/names-packages/58981/4 "2021-04-11T01:11:40Z")

</div>

I am not sure if an undisciplined collection of names, or even a collection of names and associated “general idea” labels, is a good idea. Such a collection risks becoming a source of [type puns](https://discourse.julialang.org/t/meaning-type-piracy-and-method-merging/11003/2) that confuse users and developers about what contracts the functions are supposed to have.

Two methods whose parameters are different abstract types and have no traits in common are, in my opinion, different functions. For example, in [one post](https://discourse.julialang.org/t/what-is-the-difference-between-rand-and-sample/52297/9) @Tamas_Papp said

> [@What is the difference between rand and sample?](https://discourse.julialang.org/t/what-is-the-difference-between-rand-and-sample/52297/11):
>
> I think that `Turing.sample` is OK. It just should not coincide with `StatsBase.sample` , which is a rather pointless pun.

Even within a single package, [two versions](https://discourse.julialang.org/t/sample-nchains-vs-n-chains/50336) of `StatsBase.sample` have parameters `n_chains` and `nchains`. Once multiple packages and dispatch get involved, it’ll be even more confusing.

I think it would be helpful to have declared bounds on what shared parameter names and types or traits a function accepts and returns.

---

<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:** [April 11, 2021, 4:56am UTC](https://discourse.julialang.org/t/names-packages/58981/5 "2021-04-11T04:56:02Z")

</div>

> [@cscherrer](#):
>
> This is common enough that I wonder if we should have collections of “namespace packages”.

Such packages already exist, and are conventionally named …Base.jl or similar.

Owning and providing a symbol is not sufficient, what is important is to have some definition for an API that uses those names, with changes according to SemVer. This allows dependencies to track them in a clean way.

This also means that it is better to have a small, lightweight package for each API, rather than a kitchen sink with a lot of symbols, which would require bumping versions for each unrelated change.

For statistical models, [StatsBase.jl provides this API](https://juliastats.org/StatsBase.jl/latest/statmodels/) in a rather nice way. It also has other functionality, so splitting that part could make sense. But other “statistics related” APIs that are really generic should go in similar, small packages.

---

<div class="post-metadata">

**Author:** ![tisztamo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tisztamo/32/16200_2.png) [@tisztamo](https://discourse.julialang.org/u/tisztamo)\
**Post date:** [April 11, 2021, 9:06am UTC](https://discourse.julialang.org/t/names-packages/58981/6 "2021-04-11T09:06:10Z")

</div>

> [@Tamas\_Papp](#):
>
> Such packages already exist, and are conventionally named …Base.jl or similar.
> 
> Owning and providing a symbol is not sufficient, what is important is to have some definition for an API that uses those names, with changes according to SemVer.

What do you mean with “some definition for an API”? I do not know StatsBase.jl, but it seems like (and its name suggests that) it is not just an interface, but also a partial / default / fallback (?) implementation, which also provides a type hierarchy.

My concern is that an implementation is usually more opinionated, and its opinions may diffuse into the interface undetected, hindering other implementations. On the other hand I see that providing types and basic implementations can make life easier, and that it is common practice in the Julia world.

As a concrete example, in [ActorInterfaces.Classic](https://github.com/JuliaActors/ActorInterfaces.jl/blob/main/src/Classic.jl) we already eliminated the `Actor` type, but we still have `Addr`. I like it, for me it feels like the `Addr` type glues together the whole interface into a coherent unit, but [Actors.jl](https://juliaactors.github.io/Actors.jl/dev/api/#Actors.Link) uses a different notion of links, so it has the awkward definition: `Link{C} <: ActorInterfaces.Classic.Addr`. The main point here is that addresses and links have slightly different semantics.

I would like to better understand why/when providing an implementation and root types together with the interface is the good way to go in Julia. I feel that either multiple dispatch or the nature of the community (e.g. open source, communication heavy) makes a difference to other languages, but I was not yet able to grasp it.

---

<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 11, 2021, 3:01pm UTC](https://discourse.julialang.org/t/names-packages/58981/7 "2021-04-11T15:01:04Z")

</div>

I can understand the value in what you suggest, but it also imposes some constraints on future packages. For example, StatsBase has

```julia
loglikelihood(model::StatisticalModel)

```

This doesn’t make sense to me; I would have chosen

```julia
loglikelihood(model, observation)

```

returning a function `params -> Real`.

Similarly, there are problems in Distributions.jl with types being too constrained, so they’re not usable with symbolic values. Changing this becomes increasingly difficult as more packages come to depend on it.

The problem, I think, is that pressure to commit early to this sort of thing leads to a very small window of discussion, followed by an API that’s practically set in stone.

I’ve seen cases where the “name ownership” question causes problems (the OP), and where an overly-strict API causes problems (Distributions.jl). Are there cases where a more permissive approach causes problems, in the presence of multiple dispatch?

---

<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 11, 2021, 7:01pm UTC](https://discourse.julialang.org/t/names-packages/58981/8 "2021-04-11T19:01:44Z")

</div>

I’m not sure what `loglikelihood(::StatisticalModel)` means either; maybe it’s supposed to return a function.

> [@cscherrer](#):
>
> I’ve seen cases where the “name ownership” question causes problems (the OP), and where an overly-strict API causes problems (Distributions.jl). Are there cases where a more permissive approach causes problems, in the presence of multiple dispatch?

If StatsBase had just taken the name `loglikelihood`, then different implementing packages would interpret the intent in different ways. Some might think it’s supposed to take only a model parameter; others would have it take a model and observation; still others, a model with collection of observations. Those are all different mathematical functions (`loglikelihood_function`, `loglikelihood`, `joint_loglikelihood`) and having them all use the same name is confusing. Having them all use the same Julia function is even more confusing, since then even tooling can’t help distinguish them.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [April 11, 2021, 7:15pm UTC](https://discourse.julialang.org/t/names-packages/58981/9 "2021-04-11T19:15:34Z")

</div>

> [@jzr](#):
>
> I am not sure if an undisciplined collection of names, or even a collection of names and associated “general idea” labels, is a good idea.

> [@jzr](#):
>
> If StatsBase had just taken the name `loglikelihood` , then different implementing packages would interpret the intent in different ways. Some might think it’s supposed to take only a model parameter; others would have it take a model and observation; still others, a model with collection of observations.

Did you take a look at DataAPI? There they specify a precise signature and API for their functions, e.g. [https://github.com/JuliaData/DataAPI.jl/blob/c46688cce0727cbf6912a03998675db422bb85fa/src/DataAPI.jl#L72-L96](https://github.com/JuliaData/DataAPI.jl/blob/c46688cce0727cbf6912a03998675db422bb85fa/src/DataAPI.jl#L72-L96). So while I agree that just having an assorted collection of names and nothing more is not a good idea, I also don’t think that’s what is done in practice anyway.

---

<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 11, 2021, 7:26pm UTC](https://discourse.julialang.org/t/names-packages/58981/10 "2021-04-11T19:26:20Z")

</div>

> [@ericphanson](#):
>
> specify a precise signature and API for their functions

That’s what I’m advocating. 🙂

> [@jzr](#):
>
> I think it would be helpful to have declared bounds on what shared parameter names and types or traits a function accepts and returns.

My point is that when you decide your version of `f()` takes/returns different abstract types/traits than the original, it’s time to use a different function rather than repurposing the original.

---

<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:** [April 12, 2021, 7:04am UTC](https://discourse.julialang.org/t/names-packages/58981/11 "2021-04-12T07:04:55Z")

</div>

> [@tisztamo](#):
>
> What do you mean with “some definition for an API”?

A consistent definition of an interface. Eg [the ones in `Base`](https://docs.julialang.org/en/v1/manual/interfaces/).

> [@tisztamo](#):
>
> an implementation is usually more opinionated, and its opinions may diffuse into the interface undetected, hindering other implementations

Possibly, but this does not have to be the case. Julia has a lot of well-designed interfaces, both in Base and the package ecosystem. Whether a fallback/default implementation makes sense depends on circumstances.

> [@cscherrer](#):
>
> it also imposes some constraints on future packages

Sure, all interfaces do. Designing APIs is very tricky in general, and in Julia this is complicated by performance concerns (both runtime and compile time). This requires a lot of iteration and participation from stakeholders, and occasionally a breaking change when it is warranted — this is what SemVer is for.

Eg in a future major version of StatsBase, `loglikelihood` could be fixed, even though for this particular package that is less likely because there is no single maintainer with a unifying vision. Or packages that need the concept of a `loglikelihood` along the lines you suggest (which I agree with, incidentally) could start their own lightweight API package.

> [@cscherrer](#):
>
> pressure to commit early to this sort of thing leads to a very small window of discussion

Not necessarily. A package I consider exemplary both in terms of the process and the end result is

> **[GitHub - JuliaData/Tables.jl: An interface for tables in Julia](https://github.com/JuliaData/Tables.jl)**
>
> An interface for tables in Julia. Contribute to JuliaData/Tables.jl development by creating an account on GitHub.

And, again, if an API is unsatisfactory, that’s what breaking changes are for. Nothing is fixed forever.

---

<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 12, 2021, 5:14pm UTC](https://discourse.julialang.org/t/names-packages/58981/12 "2021-04-12T17:14:09Z")

</div>

I agree APIs are important and useful. The problem they address is related to the one I’m seeing, but not entirely the same.

Suppose an API exists but doesn’t work well for your approach. Maybe there are some philosophical differences, or maybe the API was designed with assumptions that constrain the design space in a way that makes the approach you’d like to take awkward or impossible.

The obvious solution is to have a discussion with whoever is maintaining the API, and update it to suit your needs without having too great an impact on other packages. In practice, this often just doesn’t work, for a few reasons.

First, there’s usually some inherent resistance to a new approach. It can sometimes be seen as “different just to be different”. People in general often see things we have a deep understanding of as “the right way to do it” until there’s strong evidence to the contrary. And even if devs are in principle open to change, it’s sometimes clear there’s a strong preference to just leave things as they are.

Second, APIs are not developed in a vacuum. API designers almost always have particular implementations in mind as they build the abstractions. Once we have an implementation we like, we can have trouble seeing its shortcomings.

Finally, the difficulty of changing an API increases with the number of its users and reverse dependencies. The cost of negotiation can quickly become discouraging.

With all of this, it’s understandable why a new library might go outside an ill-fitting API just to get things working. But then once things work and both the API and the new library gain users, change becomes harder still, and the ecosystem more fragmented.

In any case, it’s hard to imagine a time when ever use of every name complies neatly with some widely-used API. The challenge is how to make things easily interoperable even when this isn’t the case.

---

<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 12, 2021, 7:34pm UTC](https://discourse.julialang.org/t/names-packages/58981/13 "2021-04-12T19:34:19Z")

</div>

> [@cscherrer](#):
>
> The potential benefits are pretty clear

If I understand right, we’re talking about merging two functions with different semantics into the same function object? Could you explain what you see as the benefits of doing that?

---

<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:** [April 12, 2021, 7:34pm UTC](https://discourse.julialang.org/t/names-packages/58981/14 "2021-04-12T19:34:53Z")

</div>

> [@cscherrer](#):
>
> In any case, it’s hard to imagine a time when ever use of every name complies neatly with some widely-used API. The challenge is how to make things easily interoperable even when this isn’t the case.

If they are not describing the same generic concept then they should not be methods of the same function. That’s why Julia have namespaces so you can do `Game.push!(obj::Game.Object, p::Game.Player)` to have a player push an object without it having anything to do with the `Base.push!`. Using the same names for different purposes is already easy, the solution is module namespaces.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [April 12, 2021, 7:52pm UTC](https://discourse.julialang.org/t/names-packages/58981/15 "2021-04-12T19:52:58Z")

</div>

Sorry to interfere, but it seems that discussion has deviated from the original post.

If I am getting it right, than problem is not in the API or meanings, but in the fact that

```julia
module A
    export foo
    struct A1 end
    foo(x::A1) = "hello"
end

module B
    export foo
    struct A2 end
    foo(x::A2) = "world"
end

using .A
using .B

julia> foo(A.A1())
WARNING: both B and A export "foo"; uses of it in module Main must be qualified
ERROR: UndefVarError: foo not defined

```

So, if I have some package with some functionality and for some reason implement function with the same name as in another package, suddenly everything is broken and user should use fully qualified names, which can be really tedious.

As a more concrete example, `DataFrames.jl` implements `innerjoin` function. Now, if I am implementing different data structure which also implements this function, then user workflow would look like

```julia
using DataFrames

innerjoin(df1, df2)

```

ok, let’s add another library

```julia
using DataFrames
using SomeOtherLibrary

DataFrames.innerjoin(df1, df2)

```

It’s really inconvenient and it would be much better if `DataFrames` and all other data related packages just import `innerjoin` from ome lightweight package, which only includes this common names.

I get it from this discussion, that this idea is somehow wrong, but I can’t quite understand why.  
Sorry if it is me, who deviate the discussion 🙂

---

<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 12, 2021, 8:26pm UTC](https://discourse.julialang.org/t/names-packages/58981/16 "2021-04-12T20:26:54Z")

</div>

> [@jzr](#):
>
> Could you explain what you see as the benefits of doing that?

Say we have two packages that export a `foo` function. `using` both of them forces the name to be qualified. The problem is similar to type piracy: importing one package changes the behavior of another.

We mostly have two extremes: either qualify all names, or follow a common API so the exact calls are the same.

What I’m suggesting is the possibility of a middle ground. If the methods we define are only on names we “own”, we ought to be able to still share the function and let multiple dispatch handle things for us.

> [@kristoffer.carlsson](#):
>
> Using the same names for different purposes is already easy, the solution is module namespaces.

To some extent, the problem can be addressed by expecting devs to export fewer names, or for users to only use `using` with specific names. I think the problem comes when we really want to export something and _know_ it can in principle be used with a definition from another package, though the uses might be different.

> [@Skoffer](#):
>
> Sorry to interfere, but it seems that discussion has deviated from the original post.

I think you describe the problem well, thank you for the example!

---

<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, 3:29am UTC](https://discourse.julialang.org/t/names-packages/58981/17 "2021-04-13T03:29:27Z")

</div>

> [@cscherrer](#):
>
> users to only use `using` with specific names.

This is a good idea in general since it enhances readability. It’s a bit annoying to type, but IDE tooling can help by automatically inserting `using Foo: bar, baz` statements names at the top of a file.

> [@cscherrer](#):
>
> I think the problem comes when we really want to export something and _know_ it can in principle be used with a definition from another package, though the uses might be different.

The way I like to see multimethods is something like this diagram, where the Latin-lettered objects are in some sense related to the Greek-lettered objects. For example, incrementing a : \mathbb{R} by `1` is somehow equivalent to incrementing \alpha : \mathbb{Z} by `1`, only in a different domain.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/a/ca89da96b12dd4c9c43972ebccd072c11c1da434.png)

> [@Skoffer](#):
>
> It’s really inconvenient and it would be much better if `DataFrames` and all other data related packages just import `innerjoin` from ome lightweight package, which only includes this common names.
> 
> I get it from this discussion, that this idea is somehow wrong, but I can’t quite understand why.  
> Sorry if it is me, who deviate the discussion 🙂

That’s exactly on point, not a diversion 🙂 .

I’ll take the example of `DataFrames.select`, which has

```jl
select(df::AbstractDataFrame, args...; copycols::Bool=true, renamecols::Bool=true)

```

This function has the “general idea” of “choose columns from a table”. It copies the selected columns by default, which causes a significant slowdown on large tables and deviates from the common Julia semantics of choosing elements from a collection (which doesn’t usually copy them). (BTW, I find that `Bool` flag arguments are often a sign of two functions living under the same name, which could be cleaned up by splitting them.)

Now if I define `My.select` which is another implementation of the “choose columns from a table” idea, I don’t want to use the column-copying implementation, but I do still want it to work on `DataFrames`. If I extend the hypothetical `DataFramesFunctionNames.select()`, my implementation is in conflict with `DataFrames.select()`, and I’m doing type piracy, which causes dispatch ambiguity in two senses: (1) the technical sense of which method should Julia use for `DataFramesFunctionNames.select(::DataFrame)` and (2) the semantic sense, of whether the columns should be copied. Even if I don’t need it to work on `DataFrame`s, it will still be confusing about whether columns will be copied. Therefore, I will keep `My.select` separate from `DataFrames.select` to avoid these problems, even though they both implement the same “general idea”.

---

<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:** [April 13, 2021, 7:19am UTC](https://discourse.julialang.org/t/names-packages/58981/18 "2021-04-13T07:19:10Z")

</div>

> [@cscherrer](#):
>
> `using` both of them forces the name to be qualified. The problem

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:

> [@Function name conflict: ADL / function merging?](https://discourse.julialang.org/t/function-name-conflict-adl-function-merging/10335/):
>
> Is there any reason why Julia needs me to fully qualify the function name when the argument types are clear and there shouldn’t be any problem with multiple dispatch? Case 1: load JuliaDB before defining Foo julia\> using JuliaDB julia\> stack( stack(t::D) where D\<:Union{IndexedTables.NDSparse, IndexedTables.NextTable} in IndexedTables at /Users/tomkwong/.julia/v0.6/IndexedTables/src/reshape.jl:32 stack(t::D, by; select, variable, value) where D\<:Union{IndexedTables.NDSparse, IndexedTables.Next…

---

<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:42am UTC](https://discourse.julialang.org/t/names-packages/58981/19 "2021-04-13T07:42:57Z")

</div>

To solve the issue of having to manually import names, there is this julia-vscode issue:

[https://github.com/julia-vscode/julia-vscode/issues/1925](https://github.com/julia-vscode/julia-vscode/issues/1925)

---

<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, 2:54pm UTC](https://discourse.julialang.org/t/names-packages/58981/20 "2021-04-13T14:54:58Z")

</div>

> [@jzr](#):
>
> This is a good idea in general since it enhances readability. It’s a bit annoying to type, but IDE tooling can help by automatically inserting `using Foo: bar, baz` statements names at the top of a file.

I think it depends on the context. 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.

> [@jzr](#):
>
> Now if I define `My.select` which is another implementation of the “choose columns from a table” idea, I don’t want to use the column-copying implementation, but I do still want it to work on `DataFrames` . If I extend the hypothetical `DataFramesFunctionNames.select()` , my implementation is in conflict with `DataFrames.select()` , and I’m doing type piracy, which causes dispatch ambiguity in two senses: (1) the technical sense of which method should Julia use for `DataFramesFunctionNames.select(::DataFrame)` and (2) the semantic sense, of whether the columns should be copied. Even if I don’t need it to work on `DataFrame` s, it will still be confusing about whether columns will be copied. Therefore, I will keep `My.select` separate from `DataFrames.select` to avoid these problems, even though they both implement the same “general idea”.

Right, but this is not the case I’m addressing. It’s more like the `StatsBase.loglikelihood` case. StatsBase is a pretty light-weight package, but suppose that weren’t the case. I think it’s natural to want a situation where users can have both StatsBase and my package loaded without a sudden change of behavior, and I wouldn’t have to depend directly on `StatsBase`.

What I’m suggesting for a case like this is that a new `StatsNames.jl` could contain `loglikelihood`. The “contract” would involve roughly what a log-likelihood is, and that there should be no type piracy.

What’s _not_ needed is a spec for a particular sequence of arguments. Thanks to multiple dispatch, we can add whatever methods we like. We already do this all the time within a single package.

> [@jzr](#):
>
> Those are all different mathematical functions ( `loglikelihood_function` , `loglikelihood` , `joint_loglikelihood` ) and having them all use the same name is confusing. Having them all use the same Julia function is even more confusing, since then even tooling can’t help distinguish them.

A couple of years ago I would have agreed with this. But this is a dynamic language with multiple dispatch. As long as we avoid type piracy, we can add new methods with wild abandon. I see a lot more risk in _not_ allowing this sort of thing. We get locked in to particular argument types, making it hard for new ideas to take hold.

With multiple dispatch, we can have more of a “free market” approach. With multiple methods in a single package, some will become more widely-used than others. Those that take off can be adopted by other packages.

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

```julia
StatsBase.sample(
    [rng::Random.AbstractRNG,]
    model::AbstractMCMC.AbstractModel,
    sampler::AbstractMCMC.AbstractSampler,
    nsamples[;
    kwargs...]
)

```

Among the `kwargs` is a way to specify what type of result should be returned. To me that’s not very natural; I’d rather dispatch on the type. Luckily, I’m not bound to that API; I can instead define

```julia
function sample(rng::AbstractRNG, 
    ::Type{DynamicHMCChain}, 
    m::ConditionalModel,
    nsamples::Int=1000,
    nchains::Int=4)

```

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.

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