# Forward compatibility and stability of Julia vs. Packages

**URL:** <https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968>\
**Category:** General Usage\
**Created:** [April 25, 2023, 6:09pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968 "2023-04-25T18:09:37Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [April 25, 2023, 6:09pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/1 "2023-04-25T18:09:37Z")

</div>

> [@New Julia LTS? Are many using the current (Julia 1.6) LTS?](https://discourse.julialang.org/t/new-julia-lts-are-many-using-the-current-julia-1-6-lts/93919/11):
>
> Out of curiosity, why do you want new versions of packages with old versions of Julia?

Totally agree that it’s not common, but:

> [@New Julia LTS? Are many using the current (Julia 1.6) LTS?](https://discourse.julialang.org/t/new-julia-lts-are-many-using-the-current-julia-1-6-lts/93919/11):
>
> Julia is much more stable than the package ecosystem.

It depends!  
Take a scenario where you have a project confirmed working, with a set of versions: Julia 1.x.y, PackageA 0.x.y, PackageB 1.x.y, … . And you want to update one of these versions to something newer, keeping everything else exactly as they were.  
This tends to be trivial with packages, but often not possible with Julia - at least some updates from 1.x to 1.(x+1) break lots of popular packages.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [April 26, 2023, 4:07pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/2 "2023-04-26T16:07:49Z")

</div>

Examples? The only cases I know about are packages that use/manipulate Julia internals: things like JuliaInterpreter, SnoopCompile, and Cassette. It’s expected that anything manipulating Julia’s internal representations (which are not subject to the stability guarantee) is breakable, but packages written to Julia’s public interface should not have this happen. If it’s happening to lots of things, maybe people are a wee bit too excited about metaprogramming arcana? 🙂

It’s not like we don’t do actual work to maintain compatibility: we test each Julia release candidate against the entire registered package ecosystem. By comparison, very little in the package ecosystem (with some notable exceptions, of course) goes through the same rigorous testing before release.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [April 26, 2023, 6:35pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/3 "2023-04-26T18:35:16Z")

</div>

Aside from those, popular packages shouldn’t be breaking.

Meanwhile, in the open source ecosystem, breakages are routine.  
For example, today we have a new [patch version of StatsBse](https://github.com/JuliaStats/StatsBase.jl/releases/tag/v0.33.22) which breaks [KernelDensity.jl’s precompilation](https://github.com/JuliaStats/KernelDensity.jl/issues/113), which has [271 open source dependents](https://juliahub.com/ui/Packages/KernelDensity/4QyGx/0.6.5?page=2) that now all fail to precompile and load.

This is a regular occurrence among packages, but they can thankfully be updated quickly.  
Still, you basically have to pin most packages if you have a lot of dependencies and want a stable experience.  
If you need a bug fix, I can see the appeal of upgrading exactly one thing. But Julia `1.x` to `1.(x+1)` will almost always be safer than upgrading a package `x.y.z` to `x.y.(z+1)`.  
(FWIW, this example is because of one package relying on another’s internals gratuitously. But packages do that a lot.)

---

<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 26, 2023, 6:51pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/4 "2023-04-26T18:51:58Z")

</div>

My impression is that it is actually pretty common for packages to muck around with Base internals, so it’s not always possible to update the Julia minor version while keeping all other package versions fixed. DataStructures.jl and DataFrames.jl are two popular packages that use Base internals. In particular, DataFrames.jl overloads `Base.dotview` and `Base.dotgetproperty`, which are _not_ a part of the publicly documented API for Base Julia.

See this issue for more discussion of the DataFrames situation:

> <https://github.com/JuliaData/DataFrames.jl/issues/3200>
>
> This issue is a question on the most \[recent release notes\](https://github.com/J…uliaData/DataFrames.jl/blob/8f726a6af65c64427822f75f5adaaa3df90e277a/NEWS.md#previously-announced-breaking-changes)
> 
> \> On Julia 1.7 or newer broadcasting assignment into an existing column of a data frame replaces it. Under Julia 1.6 or older it is an in place operation. (https://github.com/JuliaData/DataFrames.jl/pull/3022)
> 
> I expected \`df.col .= v\` to broadcast and do in-place assignment. But I see that's no longer the case in Dataframes.jl 1.4.
> 
> The recent release broke some code of mine (I must have missed any deprecation warnings). A simple workaround was \`coltemp = df.col; coltemp .= v\` but I don't understand the reason for the new behaviour. To me this seems to make DataFrame inconsistent with other containers in Julia and left me wondering why this inconsistency would be a wanted one.
> 
> This issue equally applies to \`df\[!, :x\] .= v\`.
> 
> Compare:
> \`\`\`
> julia\> x = \[1, 2, 3\]
> 3-element Vector{Int64}:
> 1
> 2
> 3
> 
> julia\> x .= 1.5
> ERROR: InexactError: Int64(1.5)
> \`\`\`
> 
> Whereas
> \`\`\`
> julia\> df = DataFrame(x=\[1, 2, 3\])
> 3×1 DataFrame
> Row │ x
> │ Int64
> ─────┼───────
> 1 │ 1
> 2 │ 2
> 3 │ 3
> 
> julia\> x = df.x;
> 
> julia\> df.x .= 1.5
> 3-element Vector{Float64}:
> 1.5
> 1.5
> 1.5
>  
> julia\> x === df.x
> false
> \`\`\`
> 
> As advertised \`df.x .= 1.5\` does not work in-place but replaces the column, even with a new type.
> 
> If I put the vector in any other container, say, a \`Dict\`, \`NamedTuple\` or \`struct\` 
> \`\`\`
> julia\> dt = Dict(:x=\>\[1, 2, 3\])
> Dict{Symbol, Vector{Int64}} with 1 entry:
> :x =\> \[1, 2, 3\]
> 
> julia\> dt\[:x\] .= 1.5
> ERROR: InexactError: Int64(1.5)
> 
> julia\> nt = (x = \[1, 2, 3\],)
> (x = \[1, 2, 3\],)
> 
> julia\> nt.x .= 1.5
> ERROR: InexactError: Int64(1.5)
> 
> julia\> struct S
> x
> end
> 
> julia\> s = S(\[1, 2, 3\])
> S(\[1, 2, 3\])
> 
> julia\> s.x .= 1.5
> ERROR: InexactError: Int64(1.5)
> \`\`\`
> 
> They all behave the same. But a DataFrame behaves differently. Why is that?
> 
> \---
> 
> The \[docs\](https://github.com/JuliaData/DataFrames.jl/blob/main/docs/src/man/getting\_started.md#the-dataframe-type) state "Since \`df\[!, :col\]\` does not make a copy" which to me makes it unexpected that it would create a new column rather than modifying the existing one.
> 
> \---
> 
> For the use case of "create/replace column" we have \`df.x = v\` (akin to \`s.x = v\` or \`dict\[:x\] = v\`). Would there be any adverse side-effects of letting \`=\` broadcast scalars into new/replaced columns?
> 
> \---
> 
> I understand there was a decision a year ago (#2804) to make \`df.x .= v\` work like \`d\[!,:x\] .= v\` but wouldn't a change to instead make \`df\[!,:x\] .= v\` work like \`df.x .= v\` have been more consistent with how containers in Julia typically work?

---

<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 26, 2023, 7:05pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/5 "2023-04-26T19:05:50Z")

</div>

This seems like a terrible practice. Both just add new data structures, which is the kinda of thing I never expected to mess with the internals. I would assume `JuliaInterpreter`, `SnoopCompile`, and `Cassette` need to do so and be vigilant about it, but would never have assumed the same about `Dataframes.jl` or `DataStructures.jl`.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [April 26, 2023, 7:29pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/6 "2023-04-26T19:29:21Z")

</div>

> [@tim.holy](#):
>
> Examples?

Among recent breakages that I remember - 1.9 broke SortAlgorithms, and versions before the corresponding fix don’t even precompile. So, lots of packages effectively broken by 1.9, because SortAlgorithms is a very popular dependency (eg through StatsBase).

Sure, it happens because they used some internals not covered by semver. But for the user this doesn’t change anything.

Would be interesting to test this systematically from time to time. Run tests of all packages with Julia 1.x, fixing the registry state to the release date of Julia 1.(x-1).0.

> [@New Julia LTS? Are many using the current (Julia 1.6) LTS?](https://discourse.julialang.org/t/new-julia-lts-are-many-using-the-current-julia-1-6-lts/93919/14):
>
> Julia `1.x` to `1.(x+1)` will almost always be safer than upgrading a package `x.y.z` to `x.y.(z+1)`

IME, updating a package this way almost never breaks anything. It helps that packages typically have much fewer dependents than Julia itself (everything depends on it).

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [April 26, 2023, 7:35pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/7 "2023-04-26T19:35:39Z")

</div>

> [@CameronBieganek](#):
>
> DataFrames.jl overloads `Base.dotview` and `Base.dotgetproperty`, which are _not_ a part of the publicly documented API for Base Julia.

Should´t the authors of the package make a PR to Julia to make those functions part of the documented API, if there is no solution not involving using them? That might be accepted or not, but if it is not, at least some discussion on alternatives will be stimulated, and perhaps an alternative arises.

---

<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 26, 2023, 7:40pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/8 "2023-04-26T19:40:10Z")

</div>

> [@Henrique\_Becker](#):
>
> This seems like a terrible practice. Both just add new data structures, which is the kinda of thing I never expected to mess with the internals.

I’m sure we could find more examples of using or overloading Base internals. Here are some from StaticArrays.jl:

- [`Base._getindex`](https://github.com/JuliaArrays/StaticArrays.jl/blob/2f50491b35df195d837c7123224e50f697ee180e/src/indexing.jl#L229)
- [`Base.@_inline_meta`](https://github.com/JuliaArrays/StaticArrays.jl/blob/0f68fdbd8405c1eaa0834ba062bddb6f6ecb9c47/src/pinv.jl#L39)
- [`Base.@_propagate_inbounds_meta`](https://github.com/JuliaArrays/StaticArrays.jl/blob/28e0482ba006bfb9a4a4f19dbf8b3096b2611497/src/StaticArrays.jl#L3)

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [April 26, 2023, 7:46pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/9 "2023-04-26T19:46:12Z")

</div>

The second two should definitely be removed. They aren’t needed by anyone outside of base (they are just used for bootstrapping).

---

<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 26, 2023, 7:50pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/10 "2023-04-26T19:50:19Z")

</div>

Any package that uses Julia internals and has a Julia compat that looks like this,

```julia
[compat]
julia = "1.6"

```

is using SemVer wrong. The compat should actually be like this,

```julia
[compat]
julia = "=1.6.7"

```

because even a patch release of Julia could potentially break the package. Unfortunately, I think there are a lot of packages using Julia internals with a compat entry like the former rather than the latter.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [April 26, 2023, 8:14pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/11 "2023-04-26T20:14:57Z")

</div>

1.9 is a bit of a special case, and `nightly`/`master` doesn’t count at all, because they are not actually released yet. I don’t know the specifics of the SortingAlgorithms breakage. Is it [Add comment to broken test and fix it by using Base.Sort.InitialOptimizations by LilithHafner · Pull Request #70 · JuliaCollections/SortingAlgorithms.jl · GitHub](https://github.com/JuliaCollections/SortingAlgorithms.jl/pull/70)? That seems to only be about _unreleased_ versions of Julia. Again, doesn’t really count, because the PkgEval runs only happen before release candidates and releases.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 26, 2023, 9:16pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/12 "2023-04-26T21:16:42Z")

</div>

It is fair to say that 1.9.0 cannot — by definition — break anything because it is not released yet, and that if you know of such a breakage that you should report it as a [new issue](https://github.com/JuliaLang/julia/issues/new) immediately so we can address it in the rapidly progressing 1.9.0 final release.

But I imagine the SortingAlgorithms change of note here is [JuliaCollections/SortingAlgorithms.jl#63](https://github.com/JuliaCollections/SortingAlgorithms.jl/pull/63), which was a carefully considered one-two step by a core contributor alongside [JuliaLang/julia#47383](https://github.com/JuliaLang/julia/pull/47383)… which was an explicit refactor such that the package _no longer needs to rely upon internals_. This is _exactly_ the kind of stabilization that folks are clamoring for here.

Yes, if you (or some package) have SortingAlgorithms pinned to v1.0 or prior, it won’t work with Julia v1.9. But there has always been a version of SortingAlgorithms that has worked — even against the nightly build, even immediately after the refactor’s merge. Note the merge dates: SortingAlgorithms was prepared for the refactor a month ahead of time, and we’ve had nearly half a year to move to SortingAlgorithms v1.1. And [only one now-archived package](https://juliahub.com/ui/Search?q=%5ESortingAlgorithms%5Cs%2a%3D%5Cs%2a%22%5B%5Ea%5D&type=code&r=true) pins it to anything less.

So is this _really_ an ecosystem-wide breakage? That feels a little unfair.

> [@aplavin](#):
>
> Would be interesting to test this systematically from time to time. Run tests of all packages with Julia 1.x, fixing the registry state to the release date of Julia 1.(x-1).0.

The more interesting test, in my view, is to use the latest _patch_ or _nonbreaking_ release that is compatible with the version available at the time of Julia 1.(x-1).

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [April 26, 2023, 9:28pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/13 "2023-04-26T21:28:20Z")

</div>

> [@Elrod](#):
>
> FWIW, this example is because of one package relying on another’s internals gratuitously. But packages do that a lot.

Isn’t that called type piracy, and packages shouldn’t do that in the ecosystem, no more than rely on internals in Base?

And the opposite is encapsulation, what I learned to be theoretically better… I’m conflicted here, allowing you to access the internals is powerful (sometimes needed), so shouldn’t be totally banned(?). Should it be banned by default in the (open source) package ecosystem that follows SemVer (it seems to break it, or would it be better for packages that do this that all new releases update x of x.y.z?)?

It seems that for the exceptions, something needs to be done. In C++, encapsulation is the rule (for classes), and private the default, in Julia pubic the default. But in C++ there’s another option, a friend class. Should some packages be named as friends, and evolve together? [While I’ve learned of friends in C++, I’m never used it myself, and never even heard of it used… but maybe I didn’t do too much C++… and it’s common?]

---

<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 26, 2023, 10:11pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/14 "2023-04-26T22:11:31Z")

</div>

> [@mbauman](#):
>
> Yes, if you (or some package) have SortingAlgorithms pinned to v1.0 or prior, it won’t work with Julia v1.9.

This is an avoidable situation if packages correctly specify their compat bounds. Version 1.0 of SortingAlgorithms should have had a compat similar to this:

```julia
[compat]
julia = "1.0.0 - 1.8.5"

```

DataFrames should do the same, since they also rely on undocumented Base internals.

Similarly, any package that relies on the internals of another package, like KernelDensity in the example above from @Elrod, should place a strict upper bound for the dependency at the most recent version (down to the patch number) that is known to work.

The tacit acceptance of this sort of compat fuzziness that I am seeing from core devs is discouraging. It gives me no pleasure to say this, but compatibility issues in the Julia ecosystem due to incorrect compat bounds are contributing to the sense that “Julia has correctness issues”.

There was a Github issue or PR somewhere about adding documentation for a similar compat issue, but I can’t find it right now. The issue is that any package that uses

```julia
using SomePackage

```

instead of

```julia
using SomePackage: foo

```

actually needs to place a strict upper bound on `SomePackage`, because `SomePackage` could add a new function in a minor release that creates a namespace collision. So, this is another case where loads and loads of Julia packages have incorrect compat bounds for their dependencies.

These various compat issues would probably be made a little easier if Julia had some way of marking public vs private API. I’m not sure exactly how it would work, and I’m not saying that accessing private API should be completely disallowed, but, if nothing else, it would help package authors to be more cognizant of when they are relying on internals of Julia or of other packages.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 26, 2023, 11:00pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/15 "2023-04-26T23:00:50Z")

</div>

> [@CameronBieganek](#):
>
> Version 1.0 of SortingAlgorithms should have had a compat similar to this:
> 
> ```julia
> [compat]
> julia = "1.0.0 - 1.8.5"
> 
> ```
> 
> DataFrames should do the same, since they also rely on undocumented Base internals.

Is that really helpful? Practically the effect is the same: SortingAlgorithms v1.0 cannot load on Julia v1.9. Surely it’s worse to have a situation where you’re _guaranteeing_ that each and every minor release of Julia is incompatible (by rule) with all prior versions of DataFrames.

This is why we run PkgEval.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [April 26, 2023, 11:10pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/16 "2023-04-26T23:10:11Z")

</div>

The issue with XGBoost.jl and LIBSVM.jl breaking within the Julia 1.8 series is very unfortunate.

> [@Issue with XGBoost.jl and LIBSVM.jl when Julia 1.8.4](https://discourse.julialang.org/t/issue-with-xgboost-jl-and-libsvm-jl-when-julia-1-8-4/92396):
>
> Dear all I am using XGBoost.jl v2.2.0 and LIBSVM.jl v0.8.0, under Windows 11. It works fine with Julia 1.8.3 versioninfo() Julia Version 1.8.3 Commit 0434deb161 (2022-11-14 20:14 UTC) Platform Info: OS: Windows (x86\_64-w64-mingw32) CPU: 16 × Intel(R) Core(TM) i9-10885H CPU @ 2.40GHz WORD\_SIZE: 64 LIBM: libopenlibm LLVM: libLLVM-13.0.1 (ORCJIT, skylake) Threads: 8 on 16 virtual cores Environment: JULIA\_EDITOR = code JULIA\_NUM\_THREADS = 8 But when I uses Julia 1.8.4 julia\> ver…

---

<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 26, 2023, 11:22pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/17 "2023-04-26T23:22:55Z")

</div>

> [@mbauman](#):
>
> Is that really helpful? Practically the effect is the same: SortingAlgorithms v1.0 cannot load on Julia v1.9.

Imagine I have a Project.toml file with the following compat section, and I’m running Julia v1.9:

```julia
[compat]
julia = "1.9"
SortingAlgorithms = "~1.0"

```

The package manager will happily install this environment, because SortingAlgorithms v1.0 allows any Julia version less than 2.0. But the project will be broken. I’ll say it again: the package manager will have installed a feasible set of package versions, and yet the project will be broken. That’s a correctness issue. This wouldn’t happen if SortingAlgorithms v1.0 upper bounded Julia at 1.8.5.

Besides, is it really so controversial that we actually follow semantic versioning within the Julia ecosystem?

I’ve tried to keep things simple by recommending a version bound like `julia = "1.0.0 - 1.8.5"`, but even that is not necessarily correct for a package that relies on Julia internals. For a package that uses Julia internals to list that range in the compat section, it would need to test that the package works on every single minor and patch version of Julia within that range. That might sound pedantic, but that is in fact what semantic versioning requires. This should serve as a caution to package developers to avoid using internals of other packages (or Julia) unless absolutely necessary.

---

<div class="post-metadata">

**Author:** ![j-fu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j-fu/32/11373_2.png) [@j-fu](https://discourse.julialang.org/u/j-fu)\
**Post date:** [April 26, 2023, 11:53pm UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/18 "2023-04-26T23:53:09Z")

</div>

> The issue is that any package that uses
> 
> ```julia
> using SomePackage
> 
> ```
> 
> instead of
> 
> ```julia
> using SomePackage: foo
> 
> ```
> 
> actually needs to place a strict upper bound on SomePackage, because SomePackage could add a new function in a minor release that creates a namespace collision.

Wow you have a fat point here! Noticing this for updating my packages…

From what I understand, in general Julia tries to be quite liberal with things in order to be able to explore possibilities.  
Which feels as quite the opposite approach compared to C++ and even more so Rust.

Regarding the public/private distinction AFAIK there is the convention that everything exported is public, everything else is assumed private though you can import both exported and and “private” symbols via `using SomePackage: foo`.  
IMHO it should be more visible when this privacy barrier is broken. Also, sometimes it makes sense to force qualified use of symbols by not exporting them, while still assuming them as part of the public API.

So yeah it seems there is space for improvement, and I am not sure what would be possible before 2.0…

---

<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 27, 2023, 12:19am UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/19 "2023-04-27T00:19:32Z")

</div>

I found the Github docs PR regarding recommending `using SomePackage: foo` over `using SomePackage`. The PR is still open.

> <https://github.com/JuliaLang/julia/pull/42080>
>
> I feel we are heading up against a "\`using\` crisis" where any new feature that i…s implemented by exporting a new name (either in Base or a package) becomes a breaking change. This is already happening (https://github.com/JuliaGPU/CUDA.jl/pull/1097, https://github.com/JuliaWeb/HTTP.jl/pull/745) and as projects get bigger and more names are exported, the likelihood of this rapidly increases.
> 
> The flaw in \`using Foo\` is fundamental in that you cannot lexically see where a name comes from so when two packages export the same name, you are screwed. Any code that relies on \`using Foo\` and then using an exported name from \`Foo\` is vulnerable to another dependency exporting the same name.
> Therefore, I think we should start to strongly discourage the use of \`using Foo\` and only recommend \`using Foo\` for ephemeral work (e.g. REPL work).

---

<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 27, 2023, 5:09am UTC](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968/20 "2023-04-27T05:09:45Z")

</div>

> [@CameronBieganek](#):
>
> Any package that uses Julia internals and has a Julia compat that looks like this,
> 
> ```julia
> [compat]
> julia = "1.6"
> 
> ```
> 
> is using SemVer wrong. The compat should actually be like this,
> 
> ```julia
> [compat]
> julia = "=1.6.7"
> 
> ```
> 
> because even a patch release of Julia could potentially break the package. Unfortunately, I think there are a lot of packages using Julia internals with a compat entry like the former rather than the latter.

This is not a great idea for a few reasons:

- It means we cannot even attempt to run PkgEval on the package for new Julia versions so if the package is somewhat popular we are in the dark about what effect a new Julia release will have on the ecosystem.
- It causes a lot of ovehead for package authors. They themselves cannot even test the package on newer Julia versions, they need to keep a separate branch where the compat is restricted, or they restrict it on the master branch but then you need to do backports to make releases available for the current Julia version.
- Generally, if a change to internals in Julia causes a huge disruption in the ecosystem, we try to rejigger things so that the old stuff still works. Here are some examples: [https://github.com/JuliaLang/julia/blob/3b993a958900d7f3b1aa064f2bf9e917edae0f79/base/deprecated.jl#L271-L294](https://github.com/JuliaLang/julia/blob/3b993a958900d7f3b1aa064f2bf9e917edae0f79/base/deprecated.jl#L271-L294)

[Next page](https://discourse.julialang.org/t/forward-compatibility-and-stability-of-julia-vs-packages/97968.md?page=2)
