On Sat, 17 Oct 2009 13:12:52 +0100, Tim Rowe wrote:
2009/10/17 Steven D'Aprano <steve at remove-this-cybersource.com.au>:
No, you have a fundamental misunderstanding. They're called exceptions,
not errors, because they represent exceptional cases. Often errors are
exceptional cases, but they're not the only sort of exceptional case.
The whole reason for the mechanism, across all languages that have it,
is to deal with situations that you don't know how to deal with locally.
That confuses me. If I call:
y = mydict[x]
how does my knowledge of what to do if x is not a key relate to whether
the language raises an exception, returns an error code, dumps core, or
prints "He's not the Messiah, he's a very naughty boy" to stderr?
You seem to be making a distinction of *intent* which, as far as I can
tell, doesn't actually exist. What's the difference in intent between
y = mydict[x]
if y == KeyErrorCode:
y = mydict[x]
Neither assumes more or less knowledge of what to do in
handle_error_condition(). Neither case assumes that the failure of x to
be a key is an error:
y = mydict[x]
process() # working as expected
print 'found x in dict, it shouldn't be there'
Either way, whether the language uses error codes or exceptions, the
decision of what to do in an exceptional situation is left to the user.
If you'll excuse me pointing out the bleedin' obvious, there are
differences between error codes and exceptions, but they aren't one of
intention. Error codes put the onus on the caller to check the code after
every single call which might fail (or have a buggy program), while
exceptions use a framework that do most of the heavy lifting.
That's why they have the overhead that they do.
Exceptions don't have one common overhead across all languages that use
them. They have different overhead in different languages -- they're very
heavyweight in C++ and Java, but lightweight in Python. The Perl
Exception::Base module claims to be lightweight. The overhead of
exceptions is related to the implementation of the language.
Python uses exceptions for flow control:
Yes, and in some cases I think that's a serious language wart. Not
enough to put me off the language, but a serious wart nevertheless.
I disagree with that. I think exceptions are a beautiful and powerful way
of dealing with flow control, much better than returning a special code,
and much better than having to check some status function or global
variable, as so often happens in C. They're more restricted, and
therefore safer, than goto. They're not a panacea but they're very useful.
Similarly, it's hardly an *error* for [1, 2, 3].index(5) to fail -- who
is to say that the list is supposed to have 5 in it? ValueError (a
slightly misleading name in this situation) is used to indicate an
exceptional, but not unexpected, occurrence.
That one is, I think, a legitimate use of an exception. The result
returned by index is defined if the index is in bounds. If not, index
doesn't know whether it was supposed to be in bounds or not, and so
can't handle the case locally. It could suggest an error or merely
(IMHO) poor programming. Because index cannot know what the proper
action is, an exception is the appropriate response.
I think you're confused about what list.index(obj) does. You seem to me
to be assuming that [1,2,3].index(5) should return the item in position 5
of the list, and since there isn't one (5 is out of bounds), raise an
exception. But that's not what it does. It searches the list and returns
the position at which 5 is found.
Of course list.index() could have returned an error code instead, like
str.find() does. But str also has an index() method, which raises an
exception -- when handling strings, you can Look Before You Leap or Ask
For Forgiveness Instead Of Permission, whichever you prefer.
Likewise, KeyboardInterrupt is used to allow the user to halt
processing; SystemExit is used to shut down the Python virtual machine;
and warnings are implemented using exceptions.
Again, I think it's fair to treat a program being killed from outside as
an exception as far as the program is concerned.
No, it's not being killed from outside the program -- it's being
*interrupted* from *inside* the program by the user. What you do in
response to that interrupt is up to you -- it doesn't necessarily mean
"kill the program".
If you kill the program from outside, using (say) kill or the TaskManager
or something, you don't necessarily get an exception. With kill -9 on
POSIX systems you won't get anything, because the OS will just yank the
carpet out from under your program's feet and then drop a safe on it to