Why return None?

Alex Martelli aleaxit at yahoo.com
Thu Aug 26 22:18:01 CEST 2004


Antoon Pardon <apardon at forel.vub.ac.be> wrote:
   ...
> Then python has already deviated from the one obvious way to do it.

Yep, ever since it let you code 2+3 and 3+2 with just the same effect --
which was from day one, and couldn't have been otherwise.  _Preferably_
only one way, but as I said what's preferable can't always be achieved.

Nevertheless, when for some task there _is_ one obvious way to do it,
adding a feature whose main effect would be giving two alternative
obvious ways to do it would be unPythonic.

> I can do:
> 
>   a = a + b   vs    a += b.

Yes you can, and in the general case get very different effects, e.g.:

>>> c=a=range(3)
>>> b=range(2)
>>> a+=b
>>> c
[0, 1, 2, 0, 1]

versus:

>>> c=a=range(3)
>>> b=range(2)
>>> a=a+b
>>> c
[0, 1, 2]

So, which one is the obvious way to do it depends on what 'it' is.  In
some cases it doesn't matter, just like b+a and a+b are going to have
the same effect when a and b are numbers rather than sequences, and
there's nothing Python can do to fight this -- practicality beats
purity.  If you're (when feasible) altering the object to which name 'a'
is bound, a+=b is the obvious way to do it; if you're in any case
rebinding name 'a' and letting the original object stand undisturbed,
'a=a+b' is the one obvious way to do THAT.  Not all objects can be
altered, so the first ones of these tasks isn't always going to be
feasible, of course.

> 
> or
> 
>   a = b + c   vs     a = ''.join(b,c)

You should try out the code you post, otherwise you risk ending up with
code in your face -- ''.join(b, c) will just raise an exception, which
is a VERY different effect from what b + c will give in most cases.
I'll be charitable and assume you meant ''.join((a, b)) or something
like that.

Again, it's only in one very special case that these two very different
'ways to do it' produce the same effect, just like in other different
special cases 'a = b + c' and 'a = c + b' produce the same effect and
there's nothing Python can do about it.

But let's be sensible: if 'it' is joining two strings which are bound to
names b and c, b+c is the only OBVIOUS way to do it.  Building a
sequence whose items are b and c and calling ''.join on it is clearly an
indirect and roundabout -- therefore NOT "the one obvious way"! -- to
achieve a result.  Proof: it's so unobvious, unusual, rarely used if
ever, that you typed entirely wrong code for the purpose...

Nobody ever even wished for there to never be two sequences of code with
the same end-result.  The idea (a target to strive for) is that out of
all the (probably countable) sequences with that property, ONE stands
out as so much simpler, clearer, more direct, more obvious, to make that
sequence the ONE OBVIOUS way.  We can't always get even that, as a+b vs
b+a show when a and b are bound to numbers, but we can sure get closer
to it by respecting most of GvR's design decisions than by offering
unfounded, hasty and badly reasoning critiques of them.


 
> The difference between
> 
>   print somelist.sort()
> 
> and
> 
>   somelist.sort()
>   print somelist
> 
> 
> is IMO of the same order as the difference between
> 
> 
>   print a + b
> 
> and
> 
>   r = a + b
>   print r

For a sufficiently gross-grained comparison, sure.  And so?  In the
second case, if you're not interested in having the value of a+b kept
around for any subsequent use, then the first approach is the one
obvious way; if you ARE, the second, because you've bound a name to it
(which you might have avoided) so you can reuse it (if you have no
interest in such reuse, it's not obvious why you've bound any name...).

In the first case, fortunately the first approach is illegal, the second
one is just fine.  Were they exactly equivalent in effect neither would
be the one obvious way for all reasonable observer -- some would hate
the side effect in the first case, some would hate the idea of having
two statements where one might suffice in the second case.

Fortunately the first approach does NOT do the same thing as the second
(it prints out None:-) so Python sticks to its design principles.  Let
me offer a private libation to whatever deities protect programmers,
that Python was designed by GvR rather than by people able to propose
analogies such as this last one without following through on all of
their implications and seeing why this SHOWS Python is consistent in
applying its own design principles!


Alex
 



More information about the Python-list mailing list