On Sun, 15 Jul 2012 22:15:13 -0400, Devin Jeanpierre wrote: > For example, instead of "if stack:" or "if bool(stack):", we could use > "if stack.isempty():". This line tells us explicitly that stack is a > container.
isempty is not a container method. py> container = [] py> container.isempty() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'list' object has no attribute 'isempty' Your code tells us explicitly that stack is expected to be an object with an isempty() method. What does that mean? Who knows? calories = macdonalds.fries('large') calories.isempty() => returns True When you want to write polymorphic code to handle your stack, you end up doing something like this: if isinstance(stack, MyStackClass): flag = stack.isempty() else: try: # list, collections.deque, many others flag = len(stack) == 0 except AttributeError: try: if sys.version < '3': flag = not stack.__nonzero__() else: flag = not stack.__bool__() except AttributeError: # Is this even possible in Python 3? flag = False # I guess... # If we get here, flag is true if stack is empty. if flag: ... Yeah, explicit is *so much better* for readability. Can't you just *feel* how much more readable all those irrelevant implementation details are? If you're smart, you wrap all of the above in a function: def isempty(stack): # blah blah as above But if you're *really* smart, you write to the interface and let Python take care of the polymorphic details for you: if not stack: ... (Assuming that stack defines __nonzero__ or __len__ correctly, which it better if it claims to be a container.) It boggles my mind that people who are perfectly happy to program to an interface or protocol when it comes to (say) iterables, numbers or even big complex classes with dozens of methods, suddenly freak out at the thought that you can say "if obj" and obj is duck-typed. There's a distinct lack of concrete, actual problems from duck-typing bools, and a heavy over-abundance of strongly-held opinion that such a thing is self-evidently wrong. > As far as I know, the only use of having a polymorphic boolean > conversion is reducing the amount of typing we do. The same could be said about *every* polymorphic function. The benefit is not just because you don't wear out your keyboard as fast. The benefit is the same for all other polymorphic code: it lets you write better code faster with fewer bugs and less need for unnecessary type restrictions. If there are a few corner cases where you actually *need* to restrict the type of your flags to a actual bool, well, Python gives you the tools to do so. Just as you can restrict the type of a sequence to exactly a list and nothing else, or a number as exactly a float and nothing else. Just do your type tests before you start operating on the object, and reject anything that doesn't match what you want. But that should be the exception, not the rule. > Generally objects > with otherwise different interfaces are not interchangeable just because > they can be converted to booleans, so you wouldn't lose much by being > forced to explicitly convert to boolean with something > interface-specific. Until somebody writes an awesomely fast stack class in C and gives it an is_empty() method instead of isempty, and your code can't use it because you made unnecessary assumptions about the implementation. -- Steven -- http://mail.python.org/mailman/listinfo/python-list