That's a loaded term. Technical debt also describes the design shortcuts that you take to get a product out the door, and those are much scarier than whether "range()" does the right thing or whether "print" is a function.
Yes, which is why I always love the fact that people cherry-pick examples like that and ignore things like, oh, unifying the type system, going Unicode-only for strings, adding optional annotations for type analysis...
Picking on changes like "print()" all too often betrays either ignorance of what's in Python 3.0, or a desire to misinform others about the same. I hope neither of those is your intention here.
Joel's article is about scrapping your existing codebase and starting from scratch. The discussion here is about a new version of the Python interpreter which was made from the old one by means of a bunch of incremental changes, and which will require a bunch of incremental changes in old Python code to run the old code. How is Joel's article relevant here?
Because the argument here is that it's worth breaking code to make it "cleaner", and Joel's argument is about why "clean" code is overrated. I agree that it's not a perfect match for the discussion, but it is relevant.
"Well, yes. They did. They did it by making the single worst strategic mistake that any software company can make:
They decided to rewrite the code from scratch."
"You may want to refactor a class to make it easier to use. That's fine, too. But throwing away the whole program is a dangerous folly..."
Joel is talking about rewrites, not refactorings. Py3k is more like a refactoring. You can still argue that it is ill considered, but it is not the same as what Joel is referring to.
(I suppose, technically, it is a forced refactoring for anyone who wants to use Py3k with their existing code. But still very different than a complete rewrite from scratch.)
Joel's article isn't about clean code, it's about rewriting entire codebases from scratch, which is not the same thing.
"Clean code" in general is hard to discuss because the costs and benefits of it are hard to measure or even make visible. I think in the end most people go by intuition. My intuition is that the costs of crappy code are higher than nearly anyone believes, so I'm fanatical about writing the best code I can. That doesn't mean I would go about rewriting an older module just for the sake of cleaning it up, though.
Seems a bit late in the conversation to mention this but there is no need to rewrite code to port from python 2.x to 3.0.
Basically, move to python 2.6 -- largely an incremental change. Then use the -3 switch to find all the warnings and then incrementally get rid of them. Then the 2to3 tool should take care of most of the grunt work.
Switching will be hard (all switches are) but it will not be as all-encompassing as a complete rewrite.
I think Python 3.0 is and will be a good thing even though it’ll create a staggering amount of work for me, my co-workers and my friends and colleagues (since I deal with two large Python 2.x codebases on a daily basis, the migration is not going to be simple or short for me).
So. Not a complete rewrite, but merely "a staggering amount of work"?
A number of smallish changes, applied across multiple large codebases? Yeah, that's a lot of work. Our software won't have to be completely scrapped and started over, but we will have to spend quite a lot of time porting.
In other words, if you have five hundred instances of `print "foo"` which all need to change to `print("foo")`, it's not that you have to "completely rewrite", but you _do_ have five hundred changes to make. And since applying a change is almost never as simple as a single search/replace/rename, it means work.
It will handle that one, yes, but there are enough cases where the "best" transformation is ambiguous and so has to be determined heuristically that there'll still be plenty of work left over for human programmers (not to mention cases where 2to3 cannot determine a transformation at all, or cases where it can be fooled by code which uses 3.0-isms in 2.6 code, or the need to thoroughly test, re-test and test again to make sure everything still works).
- Incorporate the -3 check with the usual unit tests and pylint run for checking a module as I work on it.
- Stay compatible with Py2.X and these additional checks, and when curiousity strikes, run 2to3 to see what happens. The codebase will probably grow some different idioms needed to clear up 2-vs-3 ambiguities; that's OK. I'll learn how to avoid these ambiguities as I go.
- When the community seems to be ready for 3.X (in particular, when Debian switches), most of the migration work will have already been done and the 2to3 script should work more or less perfectly for creating a new 3.X branch.
There's a flaw in the analogy: Very few of the original monkeys have been removed from the Python community. What Python programmers think are annoying has always simultaneously bugged the hell out of the people working on the language.
I think the author was targetting the analogy at the people who are complaining about the changes: they don't want things to break, even if it means a subpar implementation, because that's the way it has always been.