Re: Should I use "if" or "try" (as a matter of speed)?



On Sun, 10 Jul 2005 12:15:25 +0530, Dark Cowherd wrote:

> http://www.joelonsoftware.com/items/2003/10/13.html

Joel Spolsky might be a great C++ programmer, and his advice on user
interface design is invaluable, but Python is not C++ or Java, and his
arguments about exceptions do not hold in Python.

Joel argues:

"They are invisible in the source code. Looking at a block of code,
including functions which may or may not throw exceptions, there is no way
to see which exceptions might be thrown and from where. This means that
even careful code inspection doesn't reveal potential bugs."

I don't quiet get this argument. In a random piece of source code, there
is no way to tell whether or not it will fail just by inspection. If you
look at:

x = 1
result = myfunction(x)

you can't tell whether or not myfunction will fail at runtime just by
inspection, so why should it matter whether it fails by crashing at
runtime or fails by raising an exception?

Joel's argument that raising exceptions is just a goto in disguise is
partly correct. But so are for loops, while loops, functions and methods!
Like those other constructs, exceptions are gotos tamed and put to work
for you, instead of wild and dangerous. You can't jump *anywhere*, only
highly constrained places.

Joel also writes:

"They create too many possible exit points for a function. To write
correct code, you really have to think about every possible code path
through your function. Every time you call a function that can raise an
exception and don't catch it on the spot, you create opportunities for
surprise bugs caused by functions that terminated abruptly, leaving data
in an inconsistent state, or other code paths that you didn't think about."

This is a better argument for *careful* use of exceptions, not an argument
to avoid them. Or better still, it is an argument for writing code which
doesn't has side-effects and implements data transactions. That's a good
idea regardless of whether you use exceptions or not.

Joel's concern about multiple exit points is good advice, but it can be
taken too far. Consider the following code snippet:

def myfunc(x=None):
result = ""
if x is None:
result = "No argument given"
elif x = 0:
result = "Zero"
elif 0 < x <= 3:
resutl = "x is between 0 and 3"
else:
result = "x is more than 3"
return result

There is no benefit in deferring returning value as myfunc does, just
for the sake of having a single exit point. "Have a single exit point"
is a good heuristic for many functions, but it is pointless make-work for
this one. (In fact, it increases, not decreases, the chances of a bug. If
you look carefully, myfunc above has such a bug.

Used correctly, exceptions in Python have more advantages than
disadvantages. They aren't just for errors either: exceptions can be
triggered for exceptional cases (hence the name) without needing to track
(and debug) multiple special cases.

Lastly, let me argue against one of Joel's comments:

"A better alternative is to have your functions return error values when
things go wrong, and to deal with these explicitly, no matter how verbose
it might be. It is true that what should be a simple 3 line program often
blossoms to 48 lines when you put in good error checking, but that's life,
and papering it over with exceptions does not make your program more
robust."

Maybe that holds true for C++. I don't know the language, and wouldn't
like to guess. But it doesn't hold true for Python. This is how Joel might
write a function as a C programmer:

def joels_function(args):
error_result = 0
good_result = None
process(args)
if error_condition():
error_result = -1 # flag for an error
elif different_error_conditon():
error_result = -2
else:
more_processing()
if another_error_conditon():
error_result = -3
do_more_work()
good_result = "Success!"
if error_result != 0:
return (False, error_result)
else:
return (True, good_result)


and then call it with:

status, msg = joels_function(args)
if status == False:
print msg
# and fail...
else:
print msg
# and now continue...


This is how I would write it in Python:

def my_function(args):
process(args)
if error_condition():
raise SomeError("An error occurred")
elif different_error_conditon():
raise SomeError("A different error occurred")
more_processing()
if another_error_conditon():
raise SomeError("Another error occurred")
do_more_work()
return "Success!"

and call it with:

try:
result = my_function(args)
print "Success!!!"
except SomeError, msg:
print msg
# and fail...
# and now continue safely here...


In the case of Python, calling a function that may raise an exception is
no more difficult or unsafe than calling a function that returns a status
flag and a result, but writing the function itself is much easier, with
fewer places for the programmer to make a mistake.

In effect, exceptions allow the Python programmer to concentrate on his
actual program, rather than be responsible for building error-handling
infrastructure into every function. Python supplies that infrastructure
for you, in the form of exceptions.

--
Steven.

.



Relevant Pages

  • Re: Should I use "if" or "try" (as a matter of speed)?
    ... > Joel Spolsky might be a great C++ programmer, ... > arguments about exceptions do not hold in Python. ... handling is difficult and deadly boring. ...
    (comp.lang.python)
  • Re: Python or PHP?
    ... If it's one of the things for which Python ... every language here and there more ways to do something. ... you make Perl more complicated than it is:-D. ... Not the programmer. ...
    (comp.lang.python)
  • Re: Attack a sacred Python Cow
    ... Prove that implicit self is a good idea -- ... The issue here has nothing to do with the inner workings of the Python ... needs to be supplied by the programmer. ... It just occurred to me that Python could allow the ".member" access ...
    (comp.lang.python)
  • Re: True inconsistency in Python
    ... >Explicit comparison with the true constant ... In most languages (including Python), ... Now of course any idiot C programmer knows that these two are ...
    (comp.lang.python)
  • Re: C in Science and Engineering...
    ... RM> programs in ruby or python is easier than writing it in some ... requires a lot more fiddly bits and programmer attention. ... I can accomplish it with one line of Perl. ...
    (comp.lang.c)