And this old code is also written in a style (usually global variables and mixed concerns and years of sub-ideal bug fixes and patches) which makes it very hard to change or modernize (forget adding threads with all of this global mutable state).
The only point being that old code may superficially work, but in many cases (in my experience) and regardless of language, it all has technical debt and needs work to keep it relevant.
If the situation changes and the original code suddenly becomes a basis for further development then that's a different thing. But cleaning up the code without clear benefit is a waste of resources.
Hats off to original developers. Making code that serves its purpose for 25 years is quite an achievement.
All code rots. If you are lucky to never need to fix it or change it, that's great, but that is (in my experience) extremely rare over time spans measured in decades.
Sometimes a code base runs for decades not because it was particularly robust or well-written, but because it is too painful to replace it due to its complexity or the long ago loss of the knowledge needed to work on it.
Some Python users understand compiler flags, but there's also a big community of scientific developers who just want a working language.
Python 2 -> 3 created a lot of problems for them without making their lives easier or more productive.
Perhaps Python 3 should have been called something entirely different, and P2 could have been handed over to a new set of maintainers who weren't going to EOL it.
“The Fortran standards committee generally refuses to break backward compatibility when Fortran is updated. This is a good thing (take that, Python), and code written decades ago can still be compiled fine today.” -- http://degenerateconic.com/backward-compatibility/
But seriously:
- C never did such change, it doesn't make as much sense for it to do it since it is low level - C has a type static typing, so if they did, they could make compiler refuse to compile until types are right. Python has dynamic typing so these kinds of things show up when running, you can use something like mypy, but unlike C it is optional.
BTW: I saw people using Go as an example that there was no need to add unicode support like in python, and simply store everything as UTF-8. Those people are forgetting that Go already has clear distinction between text and bytes (via string, bytes, runes types), how the language stores text is just an implementation detail, since normally there shouldn't there be access to the internal representation of the text anyway.
Sure, there is some amount of C code from 25 years ago that works unchanged, but there's also a good bit of Python code from 25 years ago that works unchanged. (I just tried a few of the examples in the Python 1.3 tarball, released in 1995, and it seems like most of them will work with very minor changes.)
- Warnings recommending the use of parens in code like `if (a || b && c)`. The original code is (probably) not broken, it's just that GCC thinks that it's error-prone to write conditionals that way (I agree). There's also a similar warning for code like `while (a = foo())` where it asks you to add parens to make sure that you didn't use = instead of == by mistake.
- Warnings for unmarked fall-throughs in `switch`. Again, not broken if the fall-through was intentional. That's a fairly new warning, so a lot of all code will trigger it.
- Warnings for some const to non-const pointer conversions (in particular for literal strings in C++). There you could argue that the original code is bogus but as long as the pointer is not written to it's fine. Const-correctness wasn't really a thing in C and C++ for a long time, a lot of legacy code plays fast and loose with const qualifiers, but that doesn't necessarily mean that the code is broken.
- Warnings about unused variables, in particular variables being written to but not read. As compiler get smarter they tend to catch more of those.
Glibc and GCC introduce incompatible changes all the time.