Why Python 3.x went off course

(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at: lawrence@krubner.com, or follow me on Twitter.

A fascinating post from 2005, which is when Python began to veer off course. Python 2x had some beautiful features that could have been further developed, but instead, with 3.0, Python went down the classic Object Oriented road. In this post, Guido van van Rossum explicitly rejects much of the Functional paradigm that Python had picked up from Lisp.

So now reduce(). This is actually the one I’ve always hated most, because, apart from a few examples involving + or *, almost every time I see a reduce() call with a non-trivial function argument, I need to grab pen and paper to diagram what’s actually being fed into that function before I understand what the reduce() is supposed to do. So in my mind, the applicability of reduce() is pretty much limited to associative operators, and in all other cases it’s better to write out the accumulation loop explicitly.

I find that to be a fairly amazing statement, coming from a great programmer. His description of reduce is like the black-and-white negative of mine. I love reduce because it is like a loop, but it is cleaned up and better structured. Because reduce always takes an accumulator, it is less arbitrary than a loop. It’s also explicit that the goal of reduce is to return the accumulator, whereas a loop is a general purpose control tool which might be used to do something crazy, like produce side effects. I would guess that about 25% of all the bugs I have ever fixed have been because of the combination of mutable variables and loops, and that is because loops (as one encounters them in languages like Java or Ruby) are too open ended.

I’m having some trouble believing that Guido van van Rossum is serious in his criticism of reduce — does he need to take out pen and paper whenever he enters a loop? Because most of the time reduce is easier to understand than a loop, exactly because reduce is more strictly structured. But if he means that he likes loops better because they are imperative, and therefore he can see what is happening, then I’m confused, because elsewhere he writes about some of the problems of standard imperative programming.

And if he thought a simple reduce statement was too complicated, why did he embrace Object Oriented Programming, where one typically does need to graph the relations between objects, because the graph of relations in a non-trivial Object Oriented software project is certainly beyond what a human can comprehend.

He also makes this suggestion:

Let’s add any() and all() to the standard builtins, defined as follows (but implemented more efficiently):

    def any(S):
        for x in S:
            if x:
               return True
        return False

    def all(S):
        for x in S:
            if not x:
               return False
        return True

One of the truly terrible things in this world are programming languages that allow multiple routes of return from a function. The “return” keyword is the worst keyword in existence. I will never again willingly work in a language that supports the “return” keyword. In languages that have “return” (Javascript, PHP, Java) I have seen functions that have over a dozen possible end points. But in languages that lack “return” (such as Clojure) there is only one way for the function to end. The above cases are not so terrible, but they still allow the function to either end from a loop or end after the loop is over — it’s amazing that so much bad programming can be packed into a function that’s only 5 lines long.