Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think len() being a function instead of a method, explicitly specifying self for each method and other inconsistencies(albeit small) lead rubyists to think of python as ugly. I'm no rubyist(I prefer expediency to elegance, hence python over ruby), so take this with a grain of salt.


I think the relationship between lists, iterators, and generators is one of the greatest features of Python. I think len makes sense as a function in the same way the sum function makes sense as a function. Both do an operation on any eager iterable, including ones that don't store or "know" their own length.

The explicit self for methods comes straight out of the Python "rule" that explicit is better than implicit. Python is purposefully putting explicitness ahead of beauty, and I agree it's not particularly beautiful. Something that I find even less beautiful in Python is its super syntax:

super(theClass, self).method()

I'm still relatively new to Python, but I would argue that the super syntax goes a bit too far in explicitness (and I think it's fair to argue the same thing for the "self" in methods). Incidentally, there is a PEP (Python Enhancement Proposal) from 2007 to make super just work as super().method().

http://www.python.org/dev/peps/pep-3135/


Ironically for people still criticizing "len" as a function, it is now the more acceptable way of accomplishing the task than what Ruby is doing in many circles. In Python, len is a generic function that can call anything that implements a certain interface. This is more correct that baking the "len" function in somewhere in the object hierarchy, or implementing it relatively randomly throughout the hierarchy with a series of "len" methods that may or may not actually be connected. (len isn't the best example since it's in the "standard set", but in general just because two methods have the same name doesn't mean, well, anything in particular, really.) Favoring interfaces over inheritance leads you to the Python solution, not the Ruby solution. Python's arguably not merely "OK" but more right than Ruby here, if you are really going to be an OO purist (of certain flavors).

Python then actually ends up taking advantage of this by having len able to use any of several interfaces. It may call double-underscore-len, but it may also traverse an iterator. It could potentially do other things as well. It's actually a straightforward application of the "prefer interfaces over inheritance" to the dynamic language case. You can criticize the spelling of the double-underscore methods (which if you are really grumpy, can actually be fixed by a metaclass, though I think the cost/benefit tradeoff is bad unless you are the only person who will ever use that code), but if you haven't used them you may not realize just how finely tuned they are, and how well they work with the functions that actually search over the interfaces to find the best one to use in a way somewhat difficult to replicate directly with a "method".


    Python's arguably not merely "OK" but more right than
    Ruby here, if you are really going to be an OO purist 
    (of certain flavors).
Ruby's flavor is primarily that of sending messages to receivers (hence parens being optional). Python seems more about invoking methods on objects.


I don't think I'd call len pure for OOP. Rather, having a top-level definition--len(array) instead of array.length--gives us functional purity. That is, it discards (or hides) the concept of message passing and treats top-level methods like mathematical functions.

Lately I've heard a lot of chatter about Ruby Interfaces. They could be useful to achieve better unity. Though the Ruby collection API is already pretty consistent.


There are two nice things that you get with an explicit "self":

* You can nest classes and methods. This is ugly, so I never use it except in testsuites where declaring a mock class right in the test method is the best way to do it, but it's great to have "self" be the testcase and "xself" be the mocked method.

* There's no such thing as a magic variable. Every name you can reach is declared somewhere, either locally, globally, or from `__builtins__`. If self were automatic, then it would be invisible like the builtins, but it would change depending on where you used it from. The consistency is worth the minor inconvenience, IMHO.


the thing is, self being explicit makes it more consistent

unlike 'self' in other languages as a keyword, 'self' is just a variable with the same scoping.

i.e self always refers to the most inner scope in other languages (a special variable), meanwhile self in python is wherever self was bound in the current scope.

and fwiw: len is a holdover from earlier python (you can define a method __len__ if you want...)


> len is a holdover from earlier python

No. len is basically a multimethod.

> (you can define a method __len__ if you want…)

You have to, it's part of the length protocol, `len()` will not work if you don't. Because `len(o)` calls `o.__len__()`). If you start calling underscore-methods directly (outside of a super() access), you're heading for trouble with your coworkers.


Once you make a parameter special, subsequent effort to hide that it is special seems odd. The self parameter looked different in the call to the function.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: