Speaking as a Python outsider, this looks pathological. If backwards compatibility is such a big hindrance in switching from 2 to 3, why not ship a v2 legacy fallback interpreter along with the new stuff? If you wanted to make it fancy, you could even make a 3-to-2 bridge that allows people to run v2 code from v3.
Well, shipping an official v2 interpreter with v3 would also necessitate continuing to support the v2 code, including all its quirks that C extension modules use. So what just happened would be a necessary first step.
Then, without the fancy v2-to-v3 bridge, it wouldn't really be more useful than just having both interpreters installed separately.
The fancy bridge does sound like a cool idea. We can run Python 2 or 3 code from Julia (with limitations on the data passed between them), so why can't we run Python 2 code from Python 3, with the same limitations?
It's basically possible already with some RPC libraries, but the experience could certainly be streamlined.
The biggest issue people have with python3 is unicode support. Unlike python2 python3 puts a clear distinction between characters and bytes. It also is quite strict about it.
The problem with 2.x scripts is that they mix characters with bytes quite often. This is not something that you can easily fix by a program, because from this perspective 2.x programs are broken and need to be fixed.
What you are suggesting is already available, python 2.x and 3.x can be installed and work side by side without any issues. There's even 3-to-2 conversion tool (converting backward is much easier than the other way since python3 is more strict).
The problem really comes down to distribution maintainers, for example we are talking about Guido extending support from 2015 to 2020 for Python 2.7. So before this announcement, Python 2.7 would no longer be supported in 2015, yet we have geniuses at RedHat still shipping it with Python2.6.
And no, there is no incompatibilities between 2.6 -> 2.7 as there's from 2.x to 3.x
Hm that does sound clever. A preparser to determine what language version then invoke that interpreter. And if the 3 is so good people would switch over to usong its features only very soon.
Maybe py3 just doesnt have good enough features compared to 2 for people to make the switch and shouldnr have existed in the first place?
But gradually introducing changes.
Now python is for all intents two languages instead of one.
It's not possible to determine the language. The extensions are the same and much of the syntax hasn't changed, and many of the backwards-incompatible differences are subtle.
Python2:
print(1/2 * 1000) # 0
print({b'a': 'bytes', u'a': 'text'}[b'a']) # text
print(b'A'[0]) # A
Python3's treatment of integer literals in that case is bad. The first is the behavior that someone used to programming will expect by default, since those are integers. If you want non-integer operations you should have to use a decimal point in the 1 or 2.
I disagree. A strong type system is good, but in this case pragmatism wins the battle. I personally have been bitten innumerous times by bugs where division was rounded down (usually to 0, which is especially destructive).
Most of the numbers I encounter start as integers and most of the calculations I need are floating-point. This language behavior saves me from sprinkling "* 1.0" everywhere on my code, or from introducing extremely subtle bugs.
And the integer division is always there, one character away:
Python3's '/' operator is different from Python2's '/' operator. This is clear when you try to overload them. Python2's is called '__div__', while Python3's is '__truediv__'.
The Python3's operator '/' (on numbers) is defined to return a float, and it'll convert any integer parameters as required. The same is true for other operators, like 'True + True' being 2.
Because of these definitions, you should consider the operators as explicit conversions. 'total / sum' is less explicit than 'total / float(sum)', but still clear enough.
And about guidelines, there are others that fit this case:
Simple is better than complex.
Flat is better than nested.
Readability counts.
[...] practicality beats purity.
PS: I think you made an important argument and I'm glad you did it, even though I disagree with it. I fail to see why you are getting downvotes.
I went to check out the operation and it seems a on two ints returns an int if the power is a nonnegative int, and a float if it's negative nonzero, in both 2.7 and 3. I didn't expect this kind of inconsistency from python, really.
I guess it does follow the last line of the guidelines there, though. Looking at this power example, the division returning float now is actually an increase in consistency.
I think it's better to think of it as division being an operation that returns the appropriate type for the operation, i.e., a float where necessary. The type of the operands remain unchanged so "upcasting" is not applicable if you ask me.
Even better is that // has been available in Python 2 for ages, so you can get used to using it everywhere. Evidently they were anticipating this change.
It could work, but can you imagine the extra complexity for the interpreter? It would require extensive type conversions every time an object passes the version barrier, and all the Python3 libraries' classes would have to be backported for compatibility.
And it's not just a matter of sacrificing core dev hours for the greater good, the result would be much slower and full of gotchas.
This is a very creative idea, ingenuously simple, but I don't think it would fly.
Unfortunately there's no way in knowing whether a Python 2 string (str, not unicode) originating from the module should be interpreted as a bytes string or text string. Python 2 doesn't have the clean separation between bytes and strings.
Solutions might include adding some sort of hinting to specify the conversion, or add a Python2-like string class to Python 3, which would pollute its purity.
Am I missing something here?