On 5/21/2011 10:46 AM, John J Lee wrote:
In the absence of an explicit interface declaration (have any standards
emerged for that in Python 3, BTW?), the use of len() does give you some
information about the interface, which sometimes makes it easier to
change the function.
I'm sure you fully understand this, but I'll spell it out. Consider
this function:
def xyzzy(x):
if x:
print "yes"
To me, this trivial procedure (it is not a mathematical function) is too
unrealistic to be a basis for argument.
Let's say I've read the function, and I've seen this call site:
xyzzy(["spam", "eggs"])
Now I want to change xyzzy:
def xyzzy(x):
if x:
print "probably"
if len(x) == 1:
print "definitely"
You are not changing xyzzy, you are replacing a procedure whose domain
is all python objects with a new procedure with a much reduced domain.
In other words, you are changing (and contracting) the idea of the
procedure. This is a somewhat crazy thing to do and if Python developers
did something like that in the stdlib, I would expect multiple protest
posting ;-). (Adding code to *expand* the domain is a different matter.)
If xyzzy were really about sized collections, then
1. That should be documented *before* it is ever used in permanent code.
2. There should be code in the first production version that uses that
fact and which would raise an error on other inputs.
But there may be many call sites. Perhaps xyzzy even implements part of
a poorly-documented external API. So can x be None? There's no way to
know short of checking all call sites, which may be impossible. It may
not even be feasible to check the *only* call site, if you're
implementing somebody else's poorly documented closed-source API (a
situation I came across at work only yesterday, when that situation
resulted in a bug report). If it's written this way, it's clear that it
can't be None:
def xyzzy(x):
if len(x) != 0:
print "yes"
I agree that the domain of a function should be defined from the start
(and only expanded in the future). This means considering from the
start, or certainly once it runs correctly for intended inputs, what
will happen for other inputs. For instance, I believe functions defined
on counts (0, 1, 2, ...) should be written to avoid infinite looping on
other inputs, in particular, fractional and negative numbers. I can
imagine in theory that a gratuitous call to len() might be useful for
defining an interface, but as explained above, I am dubious about that
in practice and do not find thid example convincing.
--
Terry Jan Reedy
--
http://mail.python.org/mailman/listinfo/python-list