[Article] Dear Google Cloud: Your Deprecation Policy is Killing You

Thanks :+1:

I dunno. To me, this all sounds like a ringing endorsement for keeping deprecations around forever.

If I pick up an old code from 20 years ago and it still runs, but with deprecations suggesting I update to improved syntax / methods, that feels like a giant win to me.

I totally agree. This is not a hot burning issue by any means. Iā€™m sure v2.0 will go smooth even if there are a few small breaking changes here and there, but can there be no breaking changes at all and keep deprecations around? I donā€™t see the downside, but am open to being educated.

Totally agree, but I think we are probably past this kind of change even for v2.0. I would think any breaking change in v2.0 could surely come with deprecations.

The comment is about trying to see this problem from a different perspective. Iā€™m very much in favour of backward compatibility and in the SW project i run, weā€™re providing backward compatiblity to the users of the tool or interfaces into the tool. Itā€™s definitly hard work and puts an awful lot of constraints on new features. Still we (like my tool development) cannot avoid it, as we still compare todayā€™s output with output of some years ago (with years > 10). Steps by step if we can spend the effort, we ā€˜modernizeā€™ the SW so doing SW maintenance, but this comes at a cost.

The julia situation is something like this: you can have a breaking 2.0 at 100% development speed or a non-breaking 2.0 at a development speed of 100-x %. Out of my experience this x is rather a two-digit number and you are really lucky if the first digit is 2.

I can really recommend to read the milestones on julia issues, currently there is not much backward compatiblity visible. I understand this and see this as consistent Julia culture (i really donā€™t complain here). Changing the culture would mean that more and more people engage in contributing.

4 Likes

Thanks for clarifying :+1:

You could be right that x > 30%, but it seems a little hard for me to believe that would be the case with Julia. I think x could actually even be negative with Julia.

Looking back at v1.0, we had:

  1. Release v0.L (where ā€œLā€ is ā€œlastā€ and, in this case, L=7) with deprecations.
  2. Release v1.0 with deprecations removed so prior deprecations become errors.

Looking forward to v2.0, we could do the same thing:

  1. Release v1.L (where ā€œLā€ is ā€œlastā€) with deprecations.
  2. Release v2.0 with deprecations removed so prior deprecations become errors.

Alternatively, we could:

  1. Release v1.L-1 without deprecations.
  2. Release v2.0 with deprecations (which is effectively v1.L from above) and keep deprecations forever so that all v1 code still runs.

The latter seems like less work.

1 Like

This is not thought through to the end:

It may be less work for now (which I doubt, but ok for my argument), but it will accumulate for every future deprecations (3.0, 4.0,ā€¦). You have to take all deprecations into account for all future if you

For me it seems, that you donā€™t have much experience with maintaining and developing further a long term software project.

3 Likes

To be clear, itā€™s not that the actual non-removal of deprecations is costly. The cost comes when you want to maintain, refactor, or add new features and run into a bog of internal complexity and a combinatorial explosion of weird corner cases.

7 Likes

Google was always notorious for ā€œdeprecatingā€ their services:

I know at least 10 different Googleā€™s messaging / social network / video call apps, all dying one by one.

2 Likes

Based on how 0.7/1.0 was handled, I am assuming that this is what will happen.

This is nice because there remains a practical upgrade path remains out there forever. People could still port code from Julia 0.6 to 1.0 just by running 0.7, fixing everything (--depwarn=error is your friend), and moving on.

Of course with multiple major versions, this may become tedious. But after decades, bit rot sets in anyway; also, code that has not been touched for a long time is possibly not that useful to anyone.

10 Likes

In 20 years, do you still want all that baggage in Julia 3?

Itā€™s going to accumulate and slow down compilation.

Einstein said to make everything as simple as possible, but not simpler than that. For the sake of keeping things simple, authors should eventually move on and upgrade. Otherwise, just re-create an older environment.

8 Likes

This is true, but I think it is also true for most of the young Julia team who have been working on nothing but Julia since college so it is useful to have your perspective :slight_smile:

However, from the article, it appears that Java does precisely this too, so people who do have experience are also doing it, so worth thinking about.

Iā€™m sure youā€™re right, but I also think that Julia, with multiple dispatch, is somewhat uniquely placed to handle this smoothly. I think most maintainers would not want their users to see a bunch of deprecations so would work hard to keep everything current. Thus, avoiding the complexity at the package level.

The question is, how much complexity is the language willing to absorb to reduce complexity for the users and package maintainers? In either case, I donā€™t expect all that much complexity because Julia has, so far, done a fantastic job with compatibility.

I want to say, Iā€™m not worried about Julia 2.0 (which doesnā€™t even have a due date yet, not sure well ever get there, for any one or more of the ideas below, just discussion points), but I have full confidence in the Julia developers doing the right thing, and the old Julia LTS pre-2.0 would still work.

Thereā€™s some really good discussion here (not just on this specific name change, but on them in general, pros and cons, e.g. for beginners), and I quote Karpinski as I see he has the same idea I do:

Karpinski:

It would be trivial to have using Julia1 package that exports compatibility aliases (and methods) for >Julia 1.x names, which could be used as long as people want to.

Tim Holy (Jun 16, 2020):

[ā€¦] But yes, I donā€™t personally see any urgency for 2.0, so I expect that no one needs to be blocking out transition-time on their calendar anytime soon.

I took a look (again) at the Julia 2.0 milestone (I have one issue there that was marked 2.0) and some examples are interesting, and I comment on below.

A. For functions we could allow new functions (as we do all the time) AND keep old, that we have renamed, but it might be better to drop them (still usable with using method above and/or have choose-able with a command-line switch?).

The best answer is to @deprecate one onemult and simply not have a function called one .

As with Julia 0.7 we would deprecate, but if we wouldnā€™t get rid of one in subsequent 2.0, Iā€™m not sure what the point of the change is, since we could have using Julia1 (or Compat?).

A number of functions have been suggested to be dropped or at least no longer exported, all such could be handled this wayā€¦

B. ā€¦ but operators are more difficult. For all sane programs you should get the same result for left-to-right, vs right-to-left evaluation, i.e. the same calculated number/matrix (am I wrong about some rounding issues? I at least mean almost the same, modulo some catastrophic cancellation floating-point issues). But for + and * the associative needs to be one or the other (by default), and this can make some code order-of-magnitude faster. So I kind of want them to ā€œbreakā€ this if it helps speed, and hurts almost no code (Iā€™m not sure it would slow down, but letā€™s say you add print-statements, for debugging, they would come out in opposite order, why ā€œbreakingā€).

See workaround: Parse 1 + 2 + 3 as +(1, +(2, 3)) Ā· Issue #34999 Ā· JuliaLang/julia Ā· GitHub

C. Important to realize, Julia 1.0 only gave us syntax-guarantee (and some stability for function names), e.g. excluded was the experimental thread API (JavaCall.jl had issues because of it, now solved I understand) and while the name of the random number generation functions didnā€™t change, there was no (explicit) guarantee about the exact sequence of random-looking generated numbers (since ā€œrandomā€, seems like an edge-case to want that), later explicit warning given, so people do not assume implicit-guarantee:

[This only affects test, not users of your library, as while tests breaking, code would still work after such transition.]

In theory, this could have been solved by using Random_new in case there had been an explicit guarantee, but only for single-threaded programs. In general multi-threaded programs have non-determinism (a language like Rust is to work better with it), with or especially with random number generation.

1 Like

Just want to point out that nested quaternions and octonions are non-associative. Even though quaternions are associative, nested quaternions are not.

Also, deprecating one seems unnecessary?

1 Like

Deterministic multi-threaded or even distributed simulations are possible, if proper care is taken. Afaiu libraries like DiffEq for SDEs do take proper care.
We might even get that on the language level (for the default generator) in 1.6, if https://github.com/JuliaLang/julia/pull/34852 progresses to sufficient quality. (this would make deterministic multi-threaded random seamless and easy for the masses, not just possible for experts who code their own framework for splitting random streams).

2 Likes

There is no such thing as a non-breaking 2.0. Itā€™s an oxymoron. If it were non-breaking, then weā€™d call it 1.7, 1.8, 1.9, etc., etc. Now there are things that can help the transition ā€” things like the Compat package ā€” but requiring the addition of helper tools is also breaking.

The class of changes that is easily deprecatable/assistable by external packages are also exactly those that are easily mechanically transformed via a tool like femtocleaner. Theyā€™re also the easiest ones to tackle all around, and can be handled seamlessly in a non-breaking manner. Indeed, there are already cases where weā€™re introducing better idioms into Julia 1.x but leaving the old things around.

Version 2.0 isnā€™t for such changes.

13 Likes

See? This is the attitude that concerns me, but Iā€™m not sure it is correct. Did you read the article?

If there is a breaking change, you should bump the major version, but that doesnā€™t mean that you have to break stuff to bump a version. v2.0 could just mean that some stuff in v1.0 gets deprecated. There is no need to actually break it.

With this attitude, you are committing to zero backward compatibility at the language level.

From semver.org:

Given a version number MAJOR.MINOR.PATCH, increment the:

  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards compatible manner, and
  3. PATCH version when you make backwards compatible bug fixes.
4 Likes

Itā€™s not an attitude. Itā€™s a tautological fact. We simply wouldnā€™t call something 2.0 if itā€™s non-breaking.

Weā€™re still far away from even imagining what might be worth breaking in 2.0, but for my part I will be advocating for being hugely conservativeā€¦ and only breaking things where thereā€™s a huge and unmistakable upside, potentially weighted by the availability of upgrade tooling. Thereā€™s no need for hand-wringing ā€” at least not yet.

18 Likes

This is a simply untrue and inflammatory statement.

Regarding the thrust of your argument though, Iā€™d just say that just because making too many breaking changes too often is a bad thing, does not mean that all breaking changes are bad and they should be avoided at all costs. Thereā€™s a balance to be struck, and tooling that can be developed to mitigate the risks.

To make an analogy: driving too fast in your car is liable to kill people. This does not mean you should only drive your car at walking speeds, indeed itā€™s actually quite risky and dangerous to drive on a highway at very low speeds as well (not to mention that it kinda defeats the purpose of the vehicle)

7 Likes

If we back up a second, all I am saying here is that of all the languages out there, I think Julia can actually - at this point anyway - commit to ensuring that v1.0 code runs with v2.0, but perhaps with deprecations.

I would say that minor version bumps are for changes that do not require deprecations. You can still bump the major version and keep deprecations around.

Again, this is not a burning issue because you guys take massive effort to keep the language stable.

1 Like

What about breaking changes that are incompatible with deprecations?

2 Likes

Iā€™m not entirely sure why thereā€™s so much concern in this thread. We havenā€™t made any breaking changes in two years since 1.0 as promised. Every time 2.0 has come up, weā€™ve been very clear that breaking changes will absolutely have to justify themselves. It kind of feels like youā€™re imagining a worst case, poorly executed transition, and then arguing against that. Yes, Google sucks at this kind of thing. They donā€™t seem to even try. What reason is there to believe that we are therefore also terrible at it? We made six breaking releases of Julia leading up to 1.0 and weā€™ve made five non-breaking changes since 1.0. For the former, there was a clear upgrade path every single time: it was always possible to have the same package version working on both the previous and current major versions, preventing the sort of ecosystem upgrade deadlock that made Python 2/3 take a decade. For the latter, weā€™ve been absolutely fastidious about making sure not to break code while evolving the language.

Even when it comes to bona fide incompatible changes, there are many that would qualify as breaking by our fairly stringent standards that wouldnā€™t affect the vast majority of Julia users, or would have very minor impact (e.g. ā€œadd this using statement and your code will workā€). This category would include some type system modifications, moving stdlibs out of the standard library to become normal packages (Iā€™m looking at you, SparseArrays), and making changes to those packages that were previously stdlibs, making 2.0 releases of individual artists that were formerly stdlibs.

15 Likes