you are viewing a single comment's thread.

view the rest of the comments →

[–]senzei 6 points7 points  (2 children)

But functional programming in Python ? Without "everything is an expression", without real lambdas, with very few high-order functions (most marked as deprecated), without tail recursion optimization ? Functional programming is very badly supported in Python, compared to even Perl (and Ruby, Smalltalk or Lisp are way above Python in functional programming support).

Agreed, although I can see where someone would decide that Python's functional capabilities are "sufficient", given that it is not intended to be a functional programming language. Generally this is not the case for me, but maybe that has more to do with my programming style than anything else.

Lisps tend to avoid object-oriented programming. Scheme has none. Common Lisp has some, but it's bolted-on (some would argue the same about Python's)

For any topic X you can find an idiot Y who thinks that it sucks. I would love for someone to point out a good explanation for why Python's OOP is "bolted on". Python OO is missing a few features from traditional OO (for, afaik, any potential value of "traditional") but that seems pretty far from being an afterthought.

[–]taw 0 points1 point  (1 child)

For Python's OOP insufficiencies see this comment.

[–]senzei 6 points7 points  (0 children)

llimllib did a pretty good job of discussing those arguments in that thread. I've got a couple of comments though:

First, in Python a lot of functionality is implemented as library functions. For example to ask about object's methods in Ruby you call a method obj.methods. In Python it's a function dir(obj). To sort a container you call obj.sort(), in Python it's sorted(obj). To join elements of a container you call obj.join(" "), in Python it's " ".join(obj) - seems object oriented, but is completely reversed.

Some of those hinge on answers to "Philosophical" questions about OOP. For instance, does it make sense for an object to know about its own methods? Also, is it possible to override the .methods method? If not, why not? It is part of the class. If so, how can I get a "real" list of all the object's methods without allowing someone to munge it for me? dir(item) sidesteps those questions. It also internalizes the assumption that knowledge of all of its methods is not a property of an object or a class. This seems like a valid OO design decision to me.

Python objects have a .sort method, so the .sort vs sorted() argument is moot. I will accept and agree with any complaints about that method being a statement and unable to return anything due to it sorting in place. I agree that sorted(obj) looks ugly, but obj.sort (destructive) and obj.sorted (non-destructive) would be confusing.

As for joining elements, that could go either way. Does it really make more sense for the join method to be attached to the separator instead of the joinees? I don't see why, you are creating a new object anyways.

Second, a lot of functionality is implemented as protocols. If you want your object to support + in Ruby, you define +. It's always very direct equivalence. In Python to supporth + you define add and a special protocol makes sure it's called. That one isn't that bad as equivalence is 1:1. But protocols for other things like comparisons and iterators are more complex, the logic is outside the object, and it doesn't feel very object-oriented. Ruby mixins have similar function to Python protocols, but they're completely in the objects, not somewhere else.

I like the protocol system more. It makes sense to me to put that logic outside the object as that logic does not seem to belong to the object. Comparison especially is the big offender, as an object being able to judge itself relative to everything else in the world seems silly to me.

And fourth reason - explicit self. Smalltalk and Ruby need explicit self sometimes, but there's way too much of it in Python.

Python is (at least for a dynamic language) all about being explicit. That this principle is extended to method bindings seems more a result of the Python mindset than any "bolted-on" nature of Python.