A much better example would be something like go or java where 10 year old code still runs fine with their modern tooling. Or an even better example, perl, where 30 year old code still runs fine to this day
A much better example would be something like go or java where 10 year old code still runs fine with their modern tooling. Or an even better example, perl, where 30 year old code still runs fine to this day
As an author of software, sometimes you make mistakes, and those mistakes are often of the form, "I permitted the user to do something which I didn't intend." How do you correct something like that? In the Java world, the answer is "add newer & safer & more intentional capabilities, and encourage the user to migrate."
In the Python world, this answer is the same, but it also goes further to add, "... and turn off the old capability, SOON," which is something that Java doesn't do. In the Java world, you continue to support the old thing, basically forever, or until you have no other choice. See, for example, the equals method of java.net.URL: known to be broken, strongly discouraged, but still supported after 20+ years.
Here's an example of the difference which I'm talking about: Python Airflow has an operator which does nothing -- an empty operator. Up through a certain version, they supported calling this the DummyOperator, after an ordinary definition for "dummy." But also -- the word "dummy" has been used, historically & in certain cultures & situations, as a slur. So the Airflow maintainers said, "that's it! No more users of our software are permitted to call their operators DummyOperator -- they now must call it EmptyOperator instead!" So if you tried to upgrade, you would get an error at the time your code was loaded, until you renamed your references.
This decision has its own internal consistency, I suppose. (I personally would not break my users in this way). But in the Java world it wouldn't even be a question -- you'd support the thing until you couldn't. If the breakage in question is basically just a renaming, well, the one thing computers are good at is text substitution.
So overall & in my opinion anyway, yes, it's very much true that you can upgrade Java & Java library dependencies much more freely than you can do the same sorts of things with Python.
Man, some companies and people have far too much time to waste.
English isn't my first language but I haven't seen "dummy" being used as a slur, in any conversations I've engaged in or any books I've read. For me its connotation is more of a playful nature. When I think of slur I don't think of "dummy", I think of the r word and the like.
At least I can get the reasons for github's change to "main" for the default branch in a git repo. Maybe I don't agree with it but I can at least see how some people would interpet the word "master" in a negative way. I can't say the same for the word "dummy" though.
In python you can specify the version. The popular ML libs in Java are actually still broken and have been for years.
And I really wish ML and AI was as popular in Java as it is with Python, but I don’t see that happening anytime soon :(
Maybe it's my experiences, but I tend to do a good job avoiding dependencies.
ML is resource intensive, doesn't make sense to use JVM based languages.
I'm not sure what you mean. Python 2 to 3 was a breaking change, but that was just one change, not "constant breaking changes".
If you stick with one major version no old code breaks with a new minor version (e.g., you can run old 2.x code under 2.7 just fine, and you can run old 3.x code under 3.12 just fine). The minor version changes can add new features that your old code won't make use of (for example, old 3.x code won't use the "async" keyword or type annotations), but that doesn't make the old code break.
That said, when I look through the 3.11 release notes you refer to, I see basically three categories of such changes:
- Items that were deprecated very early in Python 3 development (3.2, for example). Since 3.3 was the first basically usable Python 3 version, I doubt there is much legacy Python 3 code that will be broken by these changes.
- Items related to early versions of new APIs introduced in Python 3 (for example, deprecating early versions of the async APIs now that async development has settled on later ones that were found to work better). These sorts of breaking changes can be avoided by not using APIs that are basically experimental and are declared to be so (as the early async APIs were).
- Items related to supporting old OSs or data formats that nobody really uses any more.
So, while these are, strictly speaking, breaking changes, I still don't think that "constant breaking changes" is a good description of the general state of Python development.
Examples?
https://docs.python.org/3.11/whatsnew/3.5.html#pep-492-corou...
Can't speak to what GP was alluding to re: breaking semantic changes.
There was also some time in the past when async became a keyword. It turned out many packages had variables named async and that caused quite a bit of pain too.
No you can't lol. There were major breaking changes from 2.4 -> 2.5, and smaller but still breaking ones for 2.5 -> 2.6.
Such as?
That said, I remember all three of those transitions (2.3 to 2.4, 2.4 to 2.5, and 2.5 to 2.6), and I remember changing Python code to make use of new features introduced in those transitions (for example, using with statements and context managers in 2.5), but those aren't breaking changes; the old code still worked, it just wasn't as robust as using the new features.
Sorry, yes, fixing a 2.4 codebase to run on 2.5. It was a while ago.
This happens a lot for me.
Use poetry? I don't program in python regularly but looking at the github repo it seems actively maintained and quite popular.
Why not simply use something stable?!
I personally don’t understand why people think such glib, throwaway comments, are helpful. They always strike me, as lacking any foresight.
How many abstractions, on the core tool, are required, to force its stability over time? What happens if poetry introduces breaking changes?
Nobody is denying that it would be ideal if there is one best solution to every problem in the ecosystem. But at the end of the day all software, including core and third party libs is just code written by people, and it is too much to expect that any person (or a group of them) gets everything right the first time. Change, breaking or otherwise, is inevitable as people learn from their mistakes - its not like the core is guaranteed to never have any breaking changes either.
Just like you can pin the version of libraries, you can pin the versions of your tools too, as long as they are not depending on external services with no versioning. The point of the post is not absolute avoidance of change. It is to opt into a workflow and tooling setup so you can deal with the upstream changes at your own time and convenience.
And BTW, looking at their versioning, poetry hasn't yet had any breaking changes in its 4+ years of existence.
The basic virtual environments work excellently too.
It’s one command more than npm install but that doesn’t mean it’s not there.
In short, you want your deployed software to use pip freeze > requirements.txt and libraries to only specify dependencies with minimal version conditions.
Edit: so if I understand it, this is just listing all packages in the current python env and writing them to a file. Hm, requires more discipline than the npm equivalent. But thats a natural consequence of pip defaulting to installing packages globally (vs npm which installs in local node_modules by default). Better but still not awesome IMO
I know it may be more complex or trivial than I think, or tied to very few specific packages, but that’s the point – I have to figure it out where I shouldn’t need to. In contrast, I’m sure that no matter which latest version of Node I have, it will work.
I mean I was, up until Node 19/20, where they broke the loader, so ts-node doesn’t work anymore and the suggestion is to re-learn something called tsx. F that nonsense.
That seems like a large amount of effort to make up for a large language deficiency. My (heartfelt) kudos to you!
I might have been willing to do the same if I used Python heavily (I don't because there are a number of other things that makes it very much "not for me") -- but it would still represent effort that shouldn't need to be engaged in.
None of this is implied by the language, I think it's much more driven by culture (though I think the final dropping of support for Python 2 did give some maintainers an excuse to do more breaking changes than was maybe required).
Your just trying to get people to use languages which are less useful in practice (other than Java).
Like a chain of tiny dicked mean people who want other people to use broken languages.
Fwiw I agree with you and you aren’t downvoted on octal.
I don't see why not. I have been writing Python for close to 20 years now, and I still have code from my early days with it that runs just fine today.
I don’t know about you. But even when I try to run 3 year old Java code with a new SDK it’s always broken somehow.
Additionally, being more strict regarding internal APIs security, not allowing access to JVM internals by naughty 3rd party libraries.
The only exception is Java 9 which removed some Java EE dependencies from JDK, but that's easily solved.
Just an example: I'm running application on Java 21 which uses Oracle 9i driver that was compiled for Java 1.4 and it works fine.
Thread.stop was deprecated very long time ago. It was deprecated at least in Java 6 (2006 year) and I'm too lazy to check for earlier versions.
Security providers have very limited usefulness for ordinary applications. And AFAIK it's not even removed for Java 21 yet, so formally old apps should work for now.
I'm not aware of incompatible JDBC interface changes and I used to use very old Oracle driver without that much problem. Yes, there are some new methods in JDBC interfaces which are not implemented with old drivers, but you can just not call those methods. It's not breaking change.
Finalizers were never reliable. But you're not correct about them not running right now, I just checked and with Java 21 they're called.
So while there are breaking changes, they're always some application issues. If you call Thread.stop, you should not do that, that's bad application. If you're using security providers, you should not do that, they're not safe enough, you should use containers or VM or other means of code isolation. I'm not completely sure about JDBC issues, but I had experience running very old JDBC driver and it works just fine. If you rely on finalizer, you should not do that, that's wrong approach to resource management and it was always wrong.
Like I said, it's application to blame.
Don't get me wrong: Python hasn't overcome its tooling problem, so there's still that barrier. But once your team agrees on a standardized tool set, you should be able to coast A-OK.
I had a similar problem moving apps from earlier versions of Java a decade ago.
Any idea what were the APIs that were likely to cause problems?
There are a handful of functions that they've deprecated, which will produce warnings from `go vet`; but that doesn't stop `go build` from producing a usable binary.
Even the cpython2 interpreter is no longer supported by the original authors, but that doesn't stop someone else from supporting it.
C# has been pretty good as well.
But at some point you're going to need data for your app and that's where you'll get surprised. That Yahoo currency data you used to get for free or Wikipedia's mobile API? Gone ten years later.
Still way better than Python, though.
Worst of all, it's always a clear "use the latest version and it will work". With python using the latest version almost always works, and you can import the previous functions if you really want to use the new interpreter on old code.
Maybe this is because most of the time with python you barely have external libraries. Similar to Java, but in Node.js it's like asking for trouble.