This is indeed a very good summary of the pitfalls. All points as
raised there are valid, I think. Unfortunately, they are as valid, or
even worse, if exceptions are unavailable or avoided. The problems that
the article describes, are inherent problems of algorithms and data
structure.
First of all, in my understanding, exceptions are not primarily a means
of error handling or treating errors in a special way. They are a means
of handling a certain condition in a graceful way - that some algorithm
should not be completed to the very end, so there is need of an
alternate exit. This is a property of many good algorithms, and since
one always needs a workaround -- alternate returns with statement
labels, logical flags, return codes, etc. -- why not use exceptions
directly? As an example, when searching for an object in a data
structure, the exception is raised as soon as the object is found, so
the search should be terminated. This is definitely not an error
condition, but a textbook example for an exception.
The next question is whether one must have special syntax for this. For
subroutines, all functionality of exceptions can be replaced by an extra
argument and a check immediately after return. This has to be done at
every stage in the call sequence. If there was a syntax that makes the
semantics more explicit, it would help the human reader to understand
the program. One would get rid of returns and conditional checks in the
middle of a subroutine and replace them by a more expressive "raise
exception" statement. In the caller, the checked block and exception
handlers would be easily visible as such. Otherwise, nothing special.
For functions, exceptions cannot be so easily be emulated. If a
function raises an exception, its result must not be digested further,
the calculation of an expression where it is embedded must be aborted,
raising the same exception again. I think this can be defined as an
addition to Fortran, but it is more subtle than subroutines. Functional
languages work perfectly with exceptions.
For parallel execution, exceptions are actually an excellent way to deal
with conditions (expected or unexpected) on individual images. I I
think I get the message of the cited paper, but in that context my
conclusion would just be the opposite. One has to think in terms of
languages such as Erlang, where this possibility is expected and built
in ('let it fail'). To make this work, exceptions would have to
cooperate well with coarrays, of course. I don't say it's easy, but I
also don't see a good alternative.
Pitfalls.
- Exceptions can screw up I/O. Yes, but this is no better and no worse
than working with IOSTAT, except that the condition cannot be ignored
anymore when it raises an exception. Handling IOSTAT is easy to forget,
like any other 'error code'. If exceptions in I/O are allowed in the
first place.
- Exceptions degrade performance. Yes, therefore I think that the set
of allowed exceptions should be explicitly declared in a procedure, in
the header. The possibility of exceptions can then be accounted for by
the compiler (explicit interface required).
- Exceptions require cleanup. Again, this is neither better nor worse
than a RETURN in the middle of a procedure. Allocatables and objects
with finalizer will be handled properly. Global state will always pose
a problem, but again this problem is not solved by avoiding exceptions,
it is a problem of the algorithm. (Actually, the language could
restrict exceptions to PURE procedures, then this problem is entirely
absent.)
- Exceptions can be ignored (while return codes are explicit). In this
respect, the article has the logic backwards.
Quote:
Forcing the calling code to handle the error right away is
the correct approach, because it forces the programmer
to think about the possibility of an error occurring.
Exceptions tend to allow, even encourage, programmers
to ignore the possibility of an error, assuming it will be
magically handled by some earlier exception handler.
Sorry, but this is nonsense. An exception that is not supported by the
procedure and handled explicitly (maybe up in the call chain), must
result in program abort. I'd expect a traceback which tells me where it
was raised. It cannot be ignored. By contrast, an error/return code
doesn't force anything, it can be silently dropped.
This article appears to be heavily influenced by experience with C++ and
its descendants, where functions have return codes and most data
structures are explicitly built with pointer hierarchies. Of course,
those are fragile. In Fortran, there are no return codes (unless the
user defines them), and one can avoid pointers entirely or use
finalizers if necessary. And Fortran has PURE, which could restrict the
use of exceptions and solve essentially all of the problems listed.
Fortran coarrays are built-in, there is no explicit communication with a
thread library, so the integration of exceptions can be controlled by
the language itself. All of this would allow a safe implementation like
it exists in various functional languages, where exceptions are actually
an integral part of the language. Apparently, the article assumes a
shared-memory situation where all kinds of collisions can occur.
Fortran's coarrays assume a multi-image setup - any image can handle its
own exceptions. Communicating exceptions might require some new additions.
I think the article completely misses the rationale for exceptions, and
the pitfalls can easily be avoided in a language that is inherently more
safe than C++. It is probably true that they can't be avoided in C++.
I don't see any advantage in the proposed traditional alternative
(numerical codes as poor-man's exceptions), because all problems are
there as well.
If the committee decides to consider exceptions, they should obviously
implement them in a way that exploits the safety measures of the
existing language. Exceptions can't work with legacy code (implit
interfaces etc.). If at all, they should be designed along coarrays
(and DO CONCURRENT, ELEMENTAL etc.).
The main point is whether the subject requires immediate attention. In
my opinion, exceptions as syntax would fill a hole in Fortran as a
modern language since they eliminate the last legitimate use of GOTO (or
any of numerous workarounds) and help the reader understand the purpose
of some particular code. But this might be pure cosmetics.
However, the feature could become extremely valuable if it would
integrate smoothly with Fortran's model of parallel execution (see
Erlang, etc.). This has to be worked out in detail. I don't find any
relevant argument in the quoted article.
-- Wolfgang
--
E-mail:
firstnameini...@domain.de
Domain: yahoo