New Julia LTS? Are many using the current (Julia 1.6) LTS?

I guess backporting public to 1.10 could be labor-intensive.

And once again: What is wrong with that?

using Compat
@compat public foo, bar

Just start using it in your package right now, and grep away @compat as soon as >1.11 becomes the next LTS your package supports. Or simply leave it forever.

5 Likes

Will there be a mention of @compat public in the Julia 1.11 release notes as an alternative for the public keyword?

1 Like

Is there a reason Compat doesn’t provide @public directly? I’d much rather write

using Compat: @public

@public my_function()
…
end

than

using Compat: @compat

@compat public my_function()
…
end

Not just from an aesthetic perspective, but also to keep shorter lines (Julia already makes it much harder than other language to keep lines below 80 characters)

Should I open a feature request for Compat?

3 Likes

From Modules · The Julia Language the suggested way of doing this would be:

module MyModule
using Compat
@compat public my_function

function my_function()
# bla bla
end

end

I’m not an expert in Compat (I only read the README.md a few hours ago), but from what I understand, the basic idea is that one puts @compat in front of the modern version of the code, so presumably the maintainers don’t want different macros for every feature that the package supports, but this is only a guess.

4 Likes

Oh, that actually makes perfect sense! I didn’t realize public was just like export, but I like it! No reason not to use @compat public in that case!

I also agree that this shouldn’t be much of a hurdle with respect to a future LTS, and that the official Julia documentation / release notes should¹ strongly encourage this use of Compat

¹ looks like at least the documentation already does, but it would probably good to mention it in the release notes as well.

5 Likes

If anything, I consider the new Memory type (expected in v1.11, I believe) to be a bigger “disruption” to the ecosystem than public (keeping in mind that neither of these changes is considered breaking). While one can continue to do everything one needs with Vector (which will become a reasonably thin wrapper over Memory), I suspect that some packages in the ecosystem that introduce data structures may change their implementations to use Memory directly. Once a package does that, I suspect its appetite for continuing support for pre-Memory versions of Julia may fade somewhat quickly.

There’s never a “right” time to bump the LTS because there’s always some “next big thing” coming just a version or two later. While many people may be excited for the steady stream of changes, these people aren’t the audience for LTS. An LTS user makes the conscious decision to forgo new features in favor of an extremely stable programming environment.

4 Likes

There’s been lots of conjecture throughout this thread about what an LTS user needs or who they are. I’ve seen three ways the LTS is helpful:

In my experience, many people that end up using the LTS do so as a response to the constraints imposed by their organization — the two most common constraints I’ve seen are glacially slow processes to approve/install executables or a literal policy that demands the LTS label. Quite ironically, in many of these orgs I’ve seen, it’s no easier to install a patch release update. So despite using the LTS Julia v1.6, they are stuck on v1.6.4 or somesuch — reaping absolutely none of the benefits of the fact that there’s subsequent patch releases available. They might as well have installed whatever was the most-recent well-cooked patch release of stable Julia at the time. But how do you know which patch releases have been well-cooked and battle tested? That’s a helpful signal the LTS designation provides, even if it’s not what it actually means.

The orgs that most benefit from the actual properties of the LTS — that is, the potential availability of patches — are those who deploy code in security sensitive situations and need to (and are able to!) update quickly with as minimal impacts as possible. Also ironically, these aren’t necessarily the “highest security” orgs because those are often completely behind airgaps and have many other mitigations in place — mitigations that slow down the introduction of new code (see above).

Finally, I do think LTS does indeed provide a nice tick-tock upgrade signal to the community at large — even for those that didn’t explicitly choose to use it. It’s a good reminder to keep up with the times and limit your technical debt. It’s a signal that package developers have often used to determine that they can start abandoning support for previous versions. And so it helps keep the Julia installs and package compatibilities cohorted together. Look at my graphs above — there’s no one adding/upgrading packages in v1.5 or earlier.

So, yes, it can be beneficial to think about the impact a particular version’s featureset will have on the package ecosystem for whatever the next “cohort” will be. But if we were to delay the LTS for a feature (or features) in v1.11 because we want the next cohort to have them, that exact rationale means we’re also delaying the incorporation of the features from v1.7, v1.8, v1.9 and v1.10 into the ecosystem. Or packages will just unilaterally start picking the one they care about (maybe it’s the property destructuring from v1.7 or the n-dimensional array literals from v1.8 or the package extensions from v1.9 or JuliaSyntax from v1.10)… and then we’d end up with a less cohesive cohort of installs and package compatibilities.

There’s always tradeoffs. And everyone will have their own weightings to them. Personally, public ain’t nothin’ compared to package extensions.

14 Likes

They are in 1.9+, and you can start using 1.10 in anticipation it will be marked LTS. It doesn’t make sense for anyone to adopt 1.6 LTS for new installations (or to support for new [package] code). In 3 months 1.6 will be 3 years old, I doubt you can expect longer support that that, so 1.10 will be supported longer even if it were not to become LTS.

I don’t understand, nobody is talking about delaying 1.7 to 1.10, 1.10 is already out (for the non-LTS package ecosystem). 1.10 can be used, you might guess it will have a year of support, but if marked LTS, 3 years, but also that’s a guess, how long has never been explicitly specified that I know of.

The Memory type is no disruption (and already in in 1.11, as I understand, just an implementation detail, no package will depend on it (am I wrong? if, then some very specialized, and such few can use conditional code, as has been done in the past to also support 1.10).

Only “syntax”/keyword changes that I recall ever breaking older Julia’s is public which will hopefully be used much, and some obscure array syntax in 1.7, relating to nD arrays, if I recall, and possibly some even more obscure added support for Unicode that could be used as operators, but unlike public it applies to few users/packages and doesn’t burden all package developers.

If we do want to have an LTS, I suggest for the next one instead of 3-year support, then a new one, only promise 2 years for critical + security fixes, and then 1 year extra for security fixes only. Then we can have a new LTS every 2 years without much maintenance burden for them. But it’s not up to me, and this seems ok even without overlapping support, that can be decided separately.

Julia is possibly not popular enough to promise much regarding LTS. Popular languages like Python, have 5 concurrently supported versions, C#, or well .NET, has 3 (and the Linux kernel has 6 longterm). I’m not suggesting more than 2 concurrent, and the new LTS would be concurrently the stable version, so this would reduce maintenance.

The public keyword is also trivially compat-able. Compat has gotten to be a bit of a large thing, I would suggest just creating a Public.jl package that defines @public to either do nothing for Julia versions pre-1.10 or emit the public keyword for 1.10+.

9 Likes

Seems easy enough; let’s do it: GitHub - JuliaLang/Public.jl

9 Likes

wouldn’t that be 1.11+

@dilumaluthge that link does not link to such a package

I’m still working on it. Check out the “Pull Requests” tab.

1 Like

Do we really need a package with such a narrow focus, instead of adding it to Compat? It seems a little odd to suggest multiple packages to enforce backward compatibility. This particular package may cease to be useful in a few years anyway, once we have a couple of new LTS releases

4 Likes

I don’t feel qualified to know whether we need it or not (sounds okay to me to have a separate package), but maybe another name would be an idea, something like PublicCompat.jl or PublicKeyword.jl might be better.

3 Likes

A better comparison might be with Scala.

1 Like

The Compat package has its share of problems. One is that it is a direct dependency of some 200 packages, with a variety of compat on its four major versions, inviting to all sorts of issues with held back packages. Another problem is that it commits to type piracy.

Maybe not every feature that could use Compat support should go into a separate package, but for a feature that we want to see widespread use of, it does seem like a good idea.

That’s perfectly fine. Some packages that use it will stop being maintained and keep depending on it forever, without causing any issues at all. Compare that to Compat, which may need to make more breaking releases in the future, where those unmaintained packages may stop being installable together with newer packages due to incompatible compat on Compat.

The only lasting cost of a specialized compat package for @public is the space of one entry in the General registry and a permanently occupied name. Which brings us to:

Agreed that using up such a general name as Public for this purpose doesn’t seem great. I propose PublicMacro.

7 Likes

100% agree. Let’s not create some mini package that will hang around in environments forever like some zombie. The solution to this is easy imo. Add to Compat or just use Meta.parse + eval if you really need this feature.

4 Likes

Also, why wasn’t this just @public in Base in the first place?

6 Likes

Matt was saying that if we avoid making 1.10 the new LTS because we desperately want features coming in 1.11, it further delays the benefits of 1.7-1.10 from getting to users of the LTS. (I know you don’t use the LTS, so this issue doesn’t matter directly to you, but it does to others.)

To summarize our options:

  1. make 1.9 the next LTS
  2. make 1.10 the next LTS
  3. release 1.11 as 1.10 + public and make it the next LTS: not gonna happen. Even if you think it’s the most important feature ever, you’ve seen first-hand that few agree with you. There’s insufficient justification for making some weird, singular kind of release that only a small fraction of the community thinks is important. We can solve it through packages like Compat.
  4. make some future version the next LTS: as Matt points out, this has its own downsides.

It seems pretty clear that either 1.9 or 1.10 should become the new LTS. Neither will have public. As we say in the US, “the grass is always greener on the other side” and we just need to get used to living with that.

2 Likes

Please don’t register it! This would make for 3rd way to define public, with similar downsides, I also think I found a 4th way, that’s near-ideal.

Right now you can:

  1. Use public as (originally, at least) intended for 1.11+ throw LTS users under the bus.
  2. Use Compat.jl
  3. Use your Public.jl, and explain it, why not 2.
  4. [Well, not right now, I’m proposing it.] Add an Julia_LTS env variable. It would work as 1. for package developers, use the most natural syntax, and need no explaining, except for (some) LTS users, those forward-looking, see below.

I know people don’t want new features (backported) in 1.10, and that may include in JuliaSyntax.jl. But semver does allow non-exported new features, i.e. when not part of API(?)

So could JuliaSyntax.jl, not be backported in whole to 1.10, but only (possibly) the public keyword, if simpler, while off by default?

Then it’s an invisible “new feature” (as if not existing), but if you run into trouble with newer packages (you will most likely if you try, not restrict yourself to older), then you can run Julia with that env set, and it fixes in all cases working with the more recent (public-using without Compat.jl or similar) packages.

Is JuliaSyntax.jl an upgradable standard library? I.e. it has its own version number, and it can be upgraded to 1.11 independently of Julia 1.10? Maybe the env var could do that, not just add one new syntax i.e. public? If it is upgradable then how would that work, all packages would have to declare using it as 1.11? I want to avoid that, why I think an ENV var is better, as much as I hate adding to many ENV vars…

Would it make any difference? It’s not too late to add to 1.11 (but please don’t until all other options explored), but like the keyword public if not backported, then has all the same problems. It’s still a hassle, plus you need to explain why one keyword in Julia is special and shouldn’t be used rather its substitute macro…

[I don’t understand this … + eval, for users, (seemingly even worse) alternative to Compat.jl or Public.jl?]

There are at least two classes of LTS users/developers. Those that want to run some already existing software (most likely would work in 1.9, so 1.9 LTS could be done right away), say for FDA approved purposes, and I know the conformance requirements are very high. What I think Matt had in mind. Right now with a new LTS you would be good for say the next three years.

Then there are forward-looking developers, that want to put their software in production for e.g. up to 3 years (not just ca. 1 and need to upgrade regularly), but that software isn’t yet finished. I.e. I want to build new software, or I’m in the middle of it, let’s say it’s ready in one year. Then 1.9 or 1.10 (without public) will be a bad option for LTS, such only works for backward-looking, i.e. the old package ecosystem.

Who are using the LTS, and what for? Can you name some example software used with it? I would love to hear more about Julia in production with or without LTS.

If people are very strict about 1.x+1.y, then I just checked if there’s a workaround, if e.g. 1.10b.1 could be used, but I (probably) discovered a bug? And this should be fixed to not parse (rather than make it ok?)

julia> v"1.10LTS.1"
v"1.10.0-LTS.1"