return None

Christopher Subich spam.csubich+block at block.subich.spam.com
Sat Jul 23 20:43:06 EDT 2005


Grant Edwards wrote:
> Personally, I don't really like the idea that falling off the
> botton of a function implicitly returns None.  It's just not
> explicit enough for me.  My preference would be that if the
> function didn't execute a "return" statement, then it didn't
> return anyting and attempting to use a return value would be an
> error.

This is a bad idea.  Classically, distinguishing between functions that 
return things and functions that don't return things explicitly divides 
the "callable object" space.  From my CS101 class with its incredibly 
exciting dive into the world of useless pseudocode, callables that 
returned things were called 'functions' and callables that didn't were 
called 'procedures'.

Some languages do make this distinction; QBASIC, for example, had 
'gosub' separate from function calls.

What do you do for an early break from a function that still returns 
not-even-None [ReallyNone], "return?"  That looks and acts like a 'real' 
return statement, and the distinction between 
return-without-a-value-so-maybe-except and return-with-a-value is 
suddenly magnified to real importance.

Further, and I consider this a truly damning case, look at decorater.  A 
naive "logging" decorator could be defined like this:

def logger(func):
    def new_func(*args, **kwargs):
       print '%s called with:' % func.__name__, args, kwargs
       retval = func(*args,**kwargs)
       print '%s returns:', retval
       return retval
    return new_func

This logger works without modification for both value and non-value 
returning functions.  Its output isn't quite as pretty for non-value 
functions, but it works and the implementation is both simple and flexible.

With a function-schism, to keep its simple implementation 'logger' would 
have to be rewritten as 'flogger' (same as current-logger, for use on 
functions), and 'plogger' (for use on procedures).  The downside here is 
that if the function/method changed to or from a procedure, the 
decorator would have to be switched.

Alternatively, the logger decorator could be longer and explicitly catch 
the possible exception.  But why should we have to write like that, for 
a use-case that doesn't even represent a true error -- arguably not even 
an exceptional case?  Python's definitely not a B&D language, talk of 
floggers aside.



More information about the Python-list mailing list