The Artima Developer Community
Sponsored Link

Python Buzz Forum
Python nit, chapter 2

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Ian Bicking

Posts: 900
Nickname: ianb
Registered: Apr, 2003

Ian Bicking is a freelance programmer
Python nit, chapter 2 Posted: Jan 13, 2004 11:59 AM
Reply to this message Reply

This post originated from an RSS feed registered with Python Buzz by Ian Bicking.
Original Post: Python nit, chapter 2
Feed Title: Ian Bicking
Feed URL: http://www.ianbicking.org/feeds/atom.xml
Feed Description: Thoughts on Python and Programming.
Latest Python Buzz Posts
Latest Python Buzz Posts by Ian Bicking
Latest Posts From Ian Bicking

Advertisement

Well, since my last complaint was over two months ago, I guess I'm fairly happy. Now I'll give something of an anti-poka-yoke

Who among us has not started with a function like:

def munger(v):
    v = mungify(v)
    return doublemungify(v)

Then realized doublemungify goes too far, and changes it to:

def munger(v):
    v = mungify(v)

But, whoops, now the function returns None. There are many ways to encounter this common bug, to unintentionally return None by not returning anything at all. Maybe one of the execution paths doesn't have a return, or you just forgot about the return at some point. It happens to me often -- but the worst part is that it's not quickly detected. Often I'll collect the results of munger, and the None will only cause a problem sometime later when it's unclear where it came from. Python nit: functions return None when you don't want them to return anything -- None is a oft-used real value, not some this-function-returns-nothing value.

It would be better if functions didn't return any value when no return (or a bare return) when encountered. So using the second munger form in an expression would cause an immediate (and informative) exception. In other words, distinguishing functions from procedures.

It seems like there's some sort of elegance in not making that distinction, in keeping these objects uniform. Plus Pascal distinguishes the two forms, and we all hate Pascal. But really, what use can there be to the implicit returning of None?

Well, one use, usually in subclassing. Supposing munger is a method, we might do:

class SafeGrinder(Grinder):
    def munger(self, v):
        if not self.isSafe(v):
            raise ValueError, "Unsafe: %s" % v
        return Grinder.munger(self, v)

Because we can always treat functions as, well, functions, we can blindly pass values through. Without this we'd need some sort of special syntax to deal with no return value, or else a way to test whether the object was a function or procedure. The test would be annoying, and would require some static declaration (e.g., two kinds of def). The static declaration would make that pass-through function even harder, because it wouldn't be sufficient to just test whether the function returned a value, we'd also have to declare whether our pass-through code was a function or procedure.

Some other syntax might be better, like (Grinder.munger(self, v) ifprocedure None), which would evaluate to None if Grinder.munger was a procedure, or the return value if not. Then you might do something like:

class OneOff: pass
class SafeGrinder(Grinder):
    def munger(self, v):
        if not self.isSafe(v): raise ValueError, "Unsafe: %s" % v
        result = Grinder.munger(self, v) ifprocedure OneOff
        if result is not OneOff: return result

Or maybe even better:

class SafeGrinder(Grinder):
    def munger(self, v):
        if not self.isSafe(v): raise ValueError, "Unsafe: %s" % v
        try:
            return Grinder.munger(self, v)
        except NoReturnValue:
            pass # and return no value

It can be a little complicated, though only for this one case, while other more common cases would be less error-prone. But it's not really going to happen in this late stage. Oh well.

Read: Python nit, chapter 2

Topic: SPF Previous Topic   Next Topic Topic: Python versus Parrot challenge

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use