Why should functions always return the same type? Why should functions always return the same type? python python

Why should functions always return the same type?


Why should functions return values of a consistent type? To meet the following two rules.

Rule 1 -- a function has a "type" -- inputs mapped to outputs. It must return a consistent type of result, or it isn't a function. It's a mess.

Mathematically, we say some function, F, is a mapping from domain, D, to range, R. F: D -> R. The domain and range form the "type" of the function. The input types and the result type are as essential to the definition of the function as is the name or the body.

Rule 2 -- when you have a "problem" or can't return a proper result, raise an exception.

def x(foo):    if 'bar' in foo:        return (foo, 'bar')     raise Exception( "oh, dear me." )

You can break the above rules, but the cost of long-term maintainability and comprehensibility is astronomical.

"Wouldn't it be cheaper memory wise to return a None?" Wrong question.

The point is not to optimize memory at the cost of clear, readable, obvious code.


It's not so clear that a function must always return objects of a limited type, or that returning None is wrong. For instance, re.search can return a _sre.SRE_Match object or a NoneType object:

import rematch=re.search('a','a')type(match)# <type '_sre.SRE_Match'>match=re.search('a','b')type(match)# <type 'NoneType'>

Designed this way, you can test for a match with the idiom

if match:    # do xyz

If the developers had required re.search to return a _sre.SRE_Match object, thenthe idiom would have to change to

if match.group(1) is None:    # do xyz

There would not be any major gain by requiring re.search to always return a _sre.SRE_Match object.

So I think how you design the function must depend on the situation and in particular, how you plan to use the function.

Also note that both _sre.SRE_Match and NoneType are instances of object, so in a broad sense they are of the same type. So the rule that "functions should always return only one type" is rather meaningless.

Having said that, there is a beautiful simplicity to functions that return objects which all share the same properties. (Duck typing, not static typing, is the python way!) It can allow you to chain together functions: foo(bar(baz))) and know with certainty the type of object you'll receive at the other end.

This can help you check the correctness of your code. By requiring that a function returns only objects of a certain limited type, there are fewer cases to check. "foo always returns an integer, so as long as an integer is expected everywhere I use foo, I'm golden..."


Best practice in what a function should return varies greatly from language to language, and even between different Python projects.

For Python in general, I agree with the premise that returning None is bad if your function generally returns an iterable, because iterating without testing becomes impossible. Just return an empty iterable in this case, it will still test False if you use Python's standard truth testing:

ret_val = x()if ret_val:     do_stuff(ret_val)

and still allow you to iterate over it without testing:

for child in x():    do_other_stuff(child)

For functions that are likely to return a single value, I think returning None is perfectly acceptable, just document that this might happen in your docstring.