The fate of reduce() in Python 3000

Link

Guido van Rossum comments on the elimination of map(), filter(), reduce() and lambda from Python 3000:

About 12 years ago, Python aquired lambda, reduce(), filter() and map(), courtesy of (I believe) a Lisp hacker who missed them and submitted working patches. But, despite of the PR value, I think these features should be cut from Python 3000.

He believes map and filter are unnecessary because there are list comprehensions. But what about reduce ? It seems Guido doesn't believe in folds:

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.

And then, with these functions gone, there is no use for lambdas, he argues.

I find it positive, in general, when designers eliminate features from a programming languages, if they are rarely used, but maybe he is being too harsh on reduce(); it may be my predilection for functional programming getting on the way, though.

via PLNews

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I think it's fascinating that

I think it's fascinating that this mystery Lisp hacker is never named, but always blamed, for submitting these implementations. =)

In Python's younger days, "map" and "filter" were often cited as examples of Python's great expressiveness, flexibility, and support for higher-order programming. "lambda" was a natural addition, since the "map" and "filter" often take functions that are rather unique and not used elsewhere. When list comprehensions were added, though, there were suddenly two ways to the same thing, and this jarred with Python's core philosophy (in strict opposition to Perl's TMTOWTDI).

Interestingly, list comprehensions suffer from the same limitation as the "crippled" lambda; they can only contain expressions. Nobody seems to complain about this fact.

In general, Python's development seems to favor the common case, making the oft-needed tools standard and accessible, at the sacrifice of the more obscure and unusual. Slicing strings and lists, for example, is a very common operation in Python programming, so there is syntax support for it. The use of map and filter were, by a large margin, the most common use of HOFs, so list comprehensions were added.

But once you've got syntax support *and* library support for something, you've got two ways to do it. And the syntactical way seems more official most of the time, so it's not surprising which way they want to eliminate.

"lambda" is a tough one, because it's undoubtedly useful, but not useful enough. Anytime someone complains that there should be a better anonymous function or block syntax, they get shot down because you can already define a named function; surely you just want anonymity so that you can write obfuscated code and make everyone get out their pen and paper. But Ruby has shown that code blocks can be added to a syntax much like Python's, and this solves the expression/statement dichotomy rather nicely (IMHO) plus it allows you do design control structures and new looping constructs that can be quite handy. I think that it's mainly an issue of style; people don't like any of the options they've seen for adding code blocks to the language because they're all "ugly" in some way or another.

Now, "reduce" is really an odd one. The reason "sum()" and friends are being added is to eliminate the only common use cases for "reduce". It's not like an FPL, where "fold" is a fundamental construct from which "map" and friends are derived. Folds favor stateless, recursive programming. Python is designed with imperative, iterative programming in mind. Once again, two ways to do it, so you've got to kill the unpopular way.

There really are very few use cases for "reduce" in Python, mainly because the common, built-in data structures (lists and dictionaries) are imperative. Reduce can be used with imperative data structures, but it's sort of silly to keep passing the accumulator around, if you're just going to mutate it anyway.

So, I'm not too sad to see reduce go away, but I do think it should be retained in a "functional" module; hopefully, this will happen at some point. It seems like Guido is a bit more open to the idea than I previously thought. Right now, "itertools" is sort of a sneaky way to get a module of functional tools into the language without actually using the f-word, and it's hard not to like "itertools" since it's based around lazy streams and thus can lead to more memory-efficient code.

Once again, I think this whole thing has way more to do with "one, and preferably only one, obvious way to do it" than with a deliberate bent against functional programming. But there is also a bit of resentment in the Python community toward "Lisp weenies", for whom Python's lambda, syntax, and (intentional) lack of macro support are never good enough. As has been pointed out already, Python and Scheme are actually quite similar, if you disregard parentheses and macros. However, the Python community seems intent on proving that Greenspun's Tenth does not apply to their language, and having "lambda" and friends lying around makes for a much harder argument.

Python is designed first and foremost to be readable, and that seems to be the motivating factor in these decisions. It's a language for the smart masses, if you will. It attracts smart people, but tries to remain understandable to many, hence the traditional control structures, block layout, emphasis on iteration over recursion, and of course, OO. These language attributes are probably not going to budge, no matter how powerful the alternatives might be.

However, if it weren't for map/filter/reduce/lambda and the exellent tutorials by David Mertz on "charming functional programming", I never would have caught on to FP, and that would have been a shame, because I've learned so much useful stuff by studying functional languages since I got a taste of FP in Python.

I would like to see Python go on being Python, but I also hope that FP is not deliberately made more difficult in Python due to political or idealistic reasons.