On Friday, February 8, 2013 9:16:42 AM UTC-6, Steven D'Aprano wrote: > Rick Johnson wrote: > > > GvR has always been reluctant to incorporate full OOP machinery for some > > reason. > > Python is a fully object oriented language. It is *more* object oriented > than, say, Java.
Oh really? *chuckles* > - everything in Python is an object, there is no distinction between "boxed" > and "unboxed" variables; Just because /everything/ in Python is an object does not mean that Python is 100% OOP. This fact is just one of the many attributes of a 100% OOP language. Yes, Python allows OOP style, but python is NOT 100% OOP! Ruby on the other hand /is/ 100% OOP. Although it has identity issues like Python. Ruby thinks it's multi-paridigm and Python thinks it's a good example of OOP. Neither are correct. > - modules are objects; > > - functions and methods are objects; > > - classes are objects in Python, and have their own class (the metaclass); > > - metaclasses themselves are also objects, and have classes of their own; > > - it's objects all the way down, at least until you reach "type" itself, > which is bootstrapped into existence by the compiler. > > > Although Python is fully object-oriented, it does not insist on one > particular style of object syntax. It allows procedural and functional > style syntax as well. Well you just defeated yourself. How can Python be 100% OOP and then allow other paradigms? > > I am not suggesting that Python be 100% OOP, HELL NO! But > > collections should have had an "isempty" method from the beginning. But > > the same argument could be made against len, any, all, etc... > > No they shouldn't. > > [...] > > Python functions operate as *protocols*. any() and all(), for example, are > excellent examples of why your suggestion fails: the principle of "Don't > Repeat Yourself". > > In Python today, any() and all() will work perfectly on ANY ITERABLE OBJECT, > for free. The developer of that object doesn't need to do anything to > support any() and all(), all she has to do is make it iterable. > > Under your suggestion, every iterable object has to implement an any() > method, and an all() method. Every iterable type has to repeat the same old > code as every other iterable type. NOT IF PYTHON WERE TRULY 100% OOP! If so, Python would have a supertype called "Collection" that wold define all methods that operate on collections. Some of these include: len, any, all, length, isempty, __getitem__, __setitem__, etc... Then any collection subtype would inherit from this supertype and get the methods for free. > > [...] > See all the pointlessly duplicated code? Now each one needs tests, and > documentation, and the amount of duplication goes through the roof. > > Now, a developer of merely average intelligence will see all that duplicated > code, and factor it out into a global function (two actually, one for > any(), one for all()): Only if that developer does not understand sub-typing! All he has to do is write the method ONE TIME in a super-type, and then inherit the method into ANY number of sub-types for free. Now, if he wants to pervert the usage of a method to fit some niche, THEN he will need to overload the method and provide proper return value. > But a developer of above average intelligence will recognise that all those > x.any() boilerplate methods are *pointless and stupid*, since you have a > function that does everything you need, for every possible iterator, for > free. All you need do is use any(obj) syntax instead of obj.any() syntax, > which also saves one keystroke. > > And a *really* smart language designer will have realised this ahead of > time, and designed the language to encourage the use of protocols like > this, instead of insisting on the slavish application of obj.method syntax. Using built-in functions to operate on objects is foolish because you are placing extra burden on the programmer to know which /functions/ work with which /types/. The *only* functions that should be global are the kind that will work on *ANY* object. But then again, the Object type could hold these methods! len, all, and any (just to name a few) only work for collections types and as such should be methods of these types. The global functions: sum, len, any, all, enumerate, map, max, min, reversed, sorted, zip can only be applied to sequence types, or subtypes of a sequence type. So using a /real/ OOP paridigm we would do the following: ## START TRUE OOP PARIDIGM ## class Object(SuperType): def __class__ def __delattr__ def __doc__ def __format__ def __getattribute__ def __init__ def __new__ def __repr__ def __setattr__ def __sizeof__ def __str__ def __subclasshook__ def true? # aka: bool def callable? def compare(other) def dir def hash def help def id def isinstance?(Type) def issubclass?(Type) def super def type class SequenceBase(Object): # Methods from object are free def __add__ def __contains__ def __delattr__ def __delitem__ def __delslice__ def __eq__ def __ge__ def __getitem__ def __getslice__ def __gt__ def __iadd__ def __imul__ def __iter__ def __le__ def __lt__ def __mul__ def __ne__ def __reduce_ex__ def __rmul__ def __setitem__ def __setslice__ def __subclasshook__ # # Interface # def iterator def length def sum def any def all def enumerate def filter(proc) def frozenset def map def max def min def reverse def reduce(proc) def slice def sort def zip class MySequencyThing(SequenceBase): # do something here class List(SequenceBase): # Methods from SequenceBase and Object are free! # # Interface # def append def count def extend def index def insert def pop def remove def reverse def sort class MyListyThing(List): # do something here ## END TRUE OOP PARIDIGM ## You see, 100% OOP uses encapsulation, inheritance, sub-typing, etc, etc... But most fundamental to OOP is interface (methods belonging to objects), not global functions applied to objects in some haphazard fashion that some self-appointed dictator pull from his backside due to his fear of true OOP style! Python is not 100% OOP. Heck you cannot fairly apply a specific percentage level because Python's level of OOP is defined by each user of the language. The best way to describe Python is as promiscuous language who secretly longs to be 100% OOP, and to fulfill this fantasy it cross-dresses in OOP lingerie on the weekends. -- http://mail.python.org/mailman/listinfo/python-list