Why exceptions shouldn't be used for flow control [Re: YAS to the "Reading line-by-line" Problem]

William Tanksley wtanksle at dolphin.openprojects.net
Wed Jun 23 21:14:44 EDT 1999


On Thu, 24 Jun 1999 11:55:35 +1200, Greg Ewing wrote:
>William Tanksley wrote:

>> Both should be handled by exception, not by returning a special
>> value.

>I don't agree with that. Reaching the end of a file while
>reading it is not exceptional enough to warrant requiring
>the use of an exception handler to catch it.

"Not exceptional enough".  What does that mean?  (I ain't never had too
much exception! ;-)

It's an exception to the behavior of a function defined to return the next
entity in a file.  It's not an exception to a function which returns the
next entity, or some reserved value otherwise.  There's no such thing as a
partial exception; it's a quality, not a quantity.

>What bothers me about using exceptions for flow control

Presumably you're talking about command flow.  Okay, but exceptions do
nothing BUT affect flow control.  What else can they do?

>in situations like this is that the effect of an exception
>handler is *non-local*, whereas what you're trying to
>catch is really only a local concern.

Is it?  Are they?  The effects of an exception toss are as local as the
user of the function want them to be.

If EOF was truly local, then file.read would always be able to decide what
to do with it -- print a message, abort(), pop up a window, or whatever
else it takes.

>When you write something like

>  while 1:
>    try:
>      line = read_me_a_line()
>    except EOFError:
>      break

>what you really mean by the try-except is "if THIS
>PARTICULAR reading operation reaches the end of
>the file". But that's not what it does - it catches
>any EOFError raised by any operation invoked by
>read_me_a_line() that wasn't caught by something
>else first.

I see your problem, but it's pretty hard to sympathize with it, at least
in this case (and it seems to me in any case).  Consider that 'for' loops
have been terminated by IndexError exceptions for a long time now, with no
problems reported.

If someone else's uncaught EOFError hits this function, something nasty is
almost always going to happen, because of how far this is away from its
correct target.  This is robust by a definition of 'robust' with which
some are not perfectly acquainted: if it fails, it does so loudly so that
the tester notices and reports the problem.

In addition, the complexity of the failure required to produce this is
pretty high.  How many files do you need to read to get the next line from
this file?  What would have happened if you'd ignored the EOF if it had
been returned otherwise?

>In my experience, that sort of behaviour tends to
>mask bugs. I prefer results which are not errors to
>be returned normally, so that I can be sure where
>they came from.

But reading data after EOF _is_ an error condition!  A normal return is
precisely what you don't want.  A normal return offers permission for the
program to keep going as usual.

What you want is not a normal return, it's an _ab_normal return. Something
like returning (int)-1 when the function's only expected to return char,
or (in Python) returning None.  The problem?  These things are SO easy to
ignore!!!!  C is famous for noiselessly casting the -1 to a char (look at
the old Bash security bug), and Python is even worse -- any return you can
possibly make will almost certainly fit in noiselessly with anything you
do with it.  This is Python's ease of use.

The only solution which works in each case is exceptions.  This doesn't
mean that using exceptions guerantees bug freedom; nothing can do that.
It simply means that it catches the majority of the bugs the majority of
the time.

You ought to feel lucky.  Some respected programming gurus recommend
calling abort() on any odd results, to make misuse of their API as
blatantly obvious as possible.

>Greg

-- 
-William "Billy" Tanksley
Utinam logica falsa tuam philosophiam totam suffodiant!
   :-: May faulty logic undermine your entire philosophy!




More information about the Python-list mailing list