Returning none

C.Laurence Gonsalves clgonsal at keeshah.penguinpowered.com
Sat Aug 28 18:55:59 EDT 1999


On Sat, 28 Aug 1999 19:45:01 GMT, Alexander Williams
<thantos at brimstone.mecha> wrote:
> On Sat, 28 Aug 1999 07:08:05 GMT, C.Laurence Gonsalves
> <clgonsal at keeshah.penguinpowered.com> wrote:
> 
> >I really *would* like to see a stronger distinction between procedures
> >and functions though. I really don't think it's right for a Python
> 
> Actually, I have a solution to this that requires absolutely no code
> changes, merely a perceptual change; to wit:
> 
> There are no procedures in Python.  There are only function calls (and
> Zuul).
> 
> The hinge-point for understanding is that Python defines a /default/
> return value for every function which is returned if there is no
> explicit return; in the case of Python this value is "None".  Seen
> from this perspective, you can complain about the default value for
> function returns and at least be conceptually accurate but can no
> longer drag a false distinction between function and procedure into
> the mix.

<sigh> I suspect you didn't read the other post I made.

Yes, I know Python only has functions. Right now it's only a convention
that if a function is intended to be used as a procedure it will return
None. This is probably why returns without values and falling off the
end of the function implicitely return None. I don't think these cases
should return None though. They should return *nothing-at-all*. The fact
that some value (None) is returned in these cases is a source of errors,
because function writers sometimes forget to return a value, and
function callers sometimes try to get a value from something that isn't
intended to return anything.

There are several ways to have the language reduce these kinds of
errors. I've suggested at least three possibilities. Some of these
proposals suggest the creation of a function/procedure distinction. I'm
fully aware that such a distinction doesn't actually exist yet.

1.  Instead of functions reaturning None, have them actually return
    nothing at all when you fall out or just say "return" (with no
    value). It would then be a runtime error to try and get the result
    of a call to a function that does this. 
    Pros: prevents people trying to get values from functions that don't
    explicitly return a value.
    Cons: since it's just a runtime error, existing code will break
    silently.

2.  Make a real distinction between functions and procedures in the
    language. Functions return a value, procedures don't. Falling out of
    functions, or using return without a value would be illegal.
    Attempting to return a value from a procedure would also be illegal.
    Procedure calls could not be used in expressions. This would be a
    runtime error.
    Pros: same as 1, plus most code won't break silently. It'll break at
    compile time.
    Cons: much more existing code will break though.

3.  Same as 2, but add in the restriction that expressions are no longer
    statements. Procedure calls would be statements, but if what you
    were calling turned out to be a function, it wouldn't get called,
    and it would be a runtime error. To call a function only for its
    side-effects, a new type of statement (a discard statement) could be
    used.
    Pros: catches even more errors, like ignoring return values
    Cons: maybe too strict for the closet Perl programmers...

So in other words, I *know* that there isn't a real existing distinction
between functions and procedures. I was suggesting that adding such a
distinction could reduce coding errors, and I was trying to describe
what such a distinction would look like.

Another idea I just thought of, sort of half way between 1 and 2:

1.5 Using plain 'return' or falling off the end of a function would
    return nothing (rather than None) just like in point idea, but it would
    also be a compile-time error to mix the two types of returns in a
    single function definition. So there wouldn't be any new keyword for
    defining procedures, but the compiler would ensure that you were
    consistent about whether you returned something or not. As in point
    1, calling a function that returns nothing, and then trying to get
    the result from it would raise an exception. This is a bit more
    implicit that proposal 2 (it implicitly determines whether what you
    want should be more procedure-ish or funtion-ish). It requires
    little or no changes to the grammar of the language. Most code that
    will break will break at compile time, and much less code will break
    than would with idea 2. The only code that would break would be:
     - functions that sometimes return a value, and sometimes don't
       (compile time failure)
     - functions that don't return anything expecting the caller to get
       the value None (runtime failure)
    Both of these practices are pretty suspicious though, and are
    probably either errors that have remained hidden, or simply bad
    coding style that should be discouraged.

-- 
  C. Laurence Gonsalves            "Any sufficiently advanced
  clgonsal at kami.com                 technology is indistinguishable
  http://www.cryogen.com/clgonsal/  from magic." -- Arthur C. Clarke




More information about the Python-list mailing list