Exception Handlers in Functional Programming Languages.
Constructs for expressing exception handling can greatly help to avoid clutter in code by allowing the programmer to separate the code to handle unusual situations from the code for the normal case. The author proposes a new approach to embed exception handlers in functional languages. The proposed approach discards the conventional view of treating exceptions, as a means of effecting a control transfer; instead, exceptions are used to change the state of an object. The two types of exceptions, terminate and resume, are treated differently. A terminate exception, when raised, is viewed as shielding the input object. On the other hand, a resume exception designates the input object as curable and requires the immediate application of a handler function. This approach enables the clean semantics of functions raising exceptions without associating any implementation restriction and without loss of the referential transparency and the commutativity properties of functions.
Introduction
Functional Programming languages (FP) [1] describe algorithms
in a clear, concise, and natural way. For any programming
language this is a highly desirable feature. In FP
programs are constructed using primitive and user-defined
functions as building blocks, and functionals or program-
forming operations as composing functions. Further, programs
exhibit a clear hierarchical structure in which high
level programs can be combined to form higher level pro-
grams. Besides, functional languages are free from side-
effects, and express parallelism in a natural way. These
properties make FP attractive not only from the theoretical
perspective, but also from the program construction
point of view.
A key issue in program construction is robustness [8].
Software reliability can be achieved by the judicious use of
fault-tolerant tools. Exception handling [4] is one of the
two techniques used for developing reliable software. Only
a few functional languages, namely Standard ML [7], Parallel
Standard ML (PSML) [6], ALEX [3], Gerald [9], and
The author is with the Department of Electrical Engineering, McGill
University, 3480 University Street, Montreal, H3A 2A7, Canada. This
research work was supported by grants received from MICRONET - Net-work
Centres of Excellence, Canada.
A preliminary version of this work has appeared in the Proceedings of
the 16th International Computer Software and Applications Conference,
Chicago, IL, 1992.
Functional Languages (FL) [2] support constructs for software
fault-tolerance. One reason that could be attributed
to this is the concise semantics and strong mathematical
properties of functional languages make proving correctness
of programs easy. Hence program verification tech-
niques, rather than fault-tolerant tools, are more popular
in functional languages. Despite this fact, we argue
that notations for exception handling are still necessary
for the following reason. The definition of exceptions is not
necessarily restricted to failures. Following Goodenough's
definition [5], we consider exceptional conditions as those
brought to the attention of the operation's invoker. That
is, we do not treat exceptions as failures. With this broadened
outlook, exception handling becomes a useful tool in
functional languages as in any other imperative language.
Exceptions are classified into two types, namely Terminate
and Resume exceptions. In this paper, we define and
develop the required notations for programming Terminate
and Resume exceptions. Though the proposed notations
can, in principle, be used for any functional or applicative
language, we choose Backus' FP [1] for expository pur-
poses. We discuss certain preliminaries on exception handling
in the next section. The same section also presents
our approach to embedding this fault-tolerant tool in FP.
The subsequent section introduces the new constructs for
programming Terminate exceptions. We present a few examples
to explain the meaning and intentions of the proposed
constructs. In Section IV, we demonstrate that the
introduction of new constructs does not destroy the algebraic
properties of FP. Section V deals with Resume ex-
ceptions. Finally, we compare our work with other related
work in Section VI.
II. Background
In this section, the concepts of exception handling are
elucidated in an imperative framework for reasons of simplicity
and ease of understanding.
A. Preliminaries
The specified services provided by a given software module
can be classified into normal (expected and desired), abnormal
(expected but undesired), and unanticipated (un-
expected and undesired) services [4, 5]. In the first case,
the execution of a module terminates normally. The second
case leads to an exceptional result. If this exception is
not handled, then the module certainly fails to provide the
specified service. To handle detected exceptions, the mod-
ule, therefore, contains exception handlers. If, despite the
occurrence of a lower level exception, the module provides
a normal service, we say that the lower level exception is
masked by the handler. On the other hand, if the module
is unable to mask a lower level exception and provides
an exceptional result, then the exception propagates to a
higher level. The last of the three cases corresponds to
an unexpected behavior of a software module. This unexpected
behavior is attributed to the existence of one or
more design faults. Either the same module or any other
lower level module can have these design faults. Unanticipated
exceptions can be handled with the help of default
exception handlers.
The notation
Procedure
has been used to indicate that a procedure P, in addition
to its normal return, also provides an exceptional return E.
(The brackets with the three dots denote the parameters of
the procedure whose details are not germane to the discus-
sion.) In the body of P, the designer can insert a construct
responsible for raising the exception as:
When condition B is true, the exception E is raised. Some
cleanup operations may be performed before signaling E.
This construct represents the case where an exception is
detected by a runtime test B. Alternatively, an exception
could be detected by the system, at run time, to signal
exceptional conditions such as arithmetic overflow, under-
flow, and illegal array index. No explicit conditions need
be programmed for such system-defined exceptions. The
point where an exception is raised (either detected by the
system or by a runtime test) is called the activation point.
A handler H for E can be associated at the place where
P is invoked as:
In fact, the handler can be associated with the invoker of
P or with any ancestors of P, if the programmer desires so.
The place where the handler is associated is termed the
association point for the exception.
Depending on the type of service required, an exception
can be of one of the two types, namely a Terminate exception
or a Resume exception [4, 5]. Consider the procedure
defined as:
Procedure
The exception E is invoked if the runtime test B is satisfied.
Following this the control transfers to the handler H. If E
is a Terminate exception, then, on completion of H, the execution
control continues from the association point. For
Resume exceptions, the statements following
are executed on completion of H. Thus, for
exceptions control switches from the activation
point to the handler and continues execution from the association
point; whereas, for Resume exceptions, the control
temporarily jumps to the handler and then returns to the
activation point (on completion of the handler). This fact
will be made use of in defining the notations for exception
handling in FP.
B. Related Issues
Bretz [3] identifies two problems in supporting exception
handling constructs in functional programming. An
exception, in imperative languages, is treated as a means
of effecting a control transfer. Hence, there is a fundamental
conflict between the functional approach followed
in functional languages and the control flow-oriented view
of exceptions. Due to this, exceptions in functional languages
can result in non-deterministic behavior of the FP
program. For example, if there are two exception points
inside a given function, the result of parallel evaluation of
the function could be different, depending on which exception
is raised first. Consider the evaluation of the function
ADD-SUBEXP defined using the ALEX syntax [3] as
signals I;
An application like
handle I:= x.x terminate
could yield 3 or 5 depending on the order of evaluation of
the subexpressions.
This problem has been considered as intrinsic to incorporating
exceptions in functional languages. Languages
ML [7] and ALEX [3] circumvent this problem by proposing
sequential execution for FP. Such a restriction is severe
and is essentially required because the control flow view
of exceptions has been carried through to functional lan-
guages. We discard this view and define the semantics of
FP functions operating on exception objects without imposing
any restriction on the execution. Though Gerald [9]
and PSML [6] allow parallel execution of subexpressions,
they retain the deterministic behavior by assigning priorities
to exceptions.
Secondly, exception handling might cause side effects in
expressions and hence might violate the property of referential
transparency. Proposed solutions [3, 7] suggest the
association of an environment with the functions. But in
our case, discarding the conventional control flow view of
exception solves this problem naturally. It has been established
in Section IV that the introduction of new constructs
does preserve the algebraic properties of functional
languages. Our approach, like PSML [6], uses error values
for handling exceptions. However, there are some important
differences between the two. Section VI brings out
these differences.
Reeves et al. [9] point out that embedding exception handling
constructs in lazy functional languages can transform
non-strict functions into hyper-strict functions. This is illustrated
with the help of the expression,
handle bad by x.0 terminate in
where \Phi is any non-strict binary operator, non-strict in
both arguments. The signal bad propagates up through the
operators and \Phi, to be handled by the respective handler
function. Even though \Phi is defined to be non-strict in
both arguments, the up-propagation of signal through \Phi
makes it strict. This is because, both subexpressions need
to be evaluated to determine whether or not they raise
any exception. Reeves et al. claim the transformation
of non-strict actors into hyper-strict actors is due to the
up-propagation of signals through non-strict operators. To
overcome this problem, the notion of down-propagation and
firewalls has been defined in [9]. In this paper, however, we
argue that it is not the up-propagation, but the persistent
nature of exception values that causes the above problem.
By this we mean that if an exception value is a part of
an object as in hX then the error signal
e, because of its special status, persists and the above
object is indistinguishable from e. This is also referred to
as following strict semantics on exception values. In Section
III-C, we illustrate this with the help of an example
and show how the above problem could be overcome by
following lazy semantics for error values.
In the following subsection we describe our approach to
incorporating exception handlers in functional languages.
C. Our Approach to Embedding Exception Handlers in FP
Exceptions
In incorporating exception handlers in FP, we discard
the conventional control flow-oriented approach. Instead
a Terminate exception is considered to shield the input
object. That is, when a Terminate exception e is raised
while applying a function F to an object X, the input
object is considered to be shielded by e. Such an object
is represented as X e . The exception object X e can
be a component of a composite object X 1 . The objects
are respectively known as fully and partially
shielded objects. A shielded object X 1 or X e
1 can have
more than one fully shielded object, possibly shielded by
different exception names, as constituent elements. Thus,
is a partially shielded
object. A fully shielded object cannot be shielded either
by the same exception or by another exception. That is,
and X e e 0
are not valid objects. However, the object
is valid, and interestingly e 0 can
be same as e. In this object we observe a hierarchy in
shielding.
Any function, except for the respective handler, operating
on a fully-shielded object is inhibited. In other words,
when an object is fully shielded, the function applied to it
behaves like the identity function. The handler H for an
exception e, when applied to X e , removes the shield of the
object and results in H : X. It must be noted that a handler
can remove only the corresponding shield. Thus, if an
object is shielded by a number of exceptions, shields can
be removed only if the respective handlers are applied in
the appropriate order. A functions operating on a partially
shielded object either behaves like the identity function or
results in the expected value depending on the semantics
of the function. This is because functions are defined to be
non-strict with respect to exception (or shielded) objects 1 .
Even though all functions are strict (over diverging computations) in
the original definition of FP, we relax this and allow functions such as
The semantics of FP functions and functional forms operating
on shielded objects and partially shielded objects
are described in the next section. The reason for choosing
non-strict semantics (henceforth non-strictness in this
paper refers to being non-strict with respect to shielded
objects) is to allow shielded objects to exist and carry over
strict FP functions and functional forms, if any, and ultimately
to be handled by the appropriate handler.
Resume Exceptions
Resume exceptions are handled as locally as possible and
therefore embedding them in functional languages does not
cause any fundamental conflict. Since Resume exceptions
are handled locally, the concept of shielding an object does
not help. However, such sophisticated handling is not required
for Resume exceptions if we view the situation in
the following manner. When a Resume exception is raised,
the input object is considered to have some abnormality
which needs to be cured immediately. Instead of passing
the object (possibly with a shield) to the handler, the handler
is invoked at the activation point as an immediate cure
function. Such a view is simple and serves the purpose.
In the following sections, we introduce notations and
constructs for Terminate and Resume exceptions. As the
new constructs are defined, the domain and semantics of
the FP functions will be redefined as required.
III. Terminate Exceptions
The objects, functions, and functional forms of FP are
extended in the following way to embed Terminate exceptions

A. The Extended FP System
Objects
Formally, an object can be undefined (denoted by ?), or
an atom X, or a sequence of objects hX
each X i which could be (i) normal object, (ii) partially
shielded, or (iii) completely shielded by a single exception.
That is the domain O of objects can be divided into three
disjoint sets, namely (i) the set C of completely shielded objects
of the form X e , (ii) the set P of partially shielded objects
of the form hX
such that and (iii) the set N of normal (not
shielded) objects of the form hX
P. The sets N ; P, and C are such that
O
Primitive Functions
The semantics of the primitive functions operating on
shielded objects is defined below. The meaning of these
functions when applied to normal objects is as in [1].
select, tail, and null, and functionals such as construction and constant
to be non-strict in the appropriate components of the input object. We
chose non-strict semantics as we want to show that our approach to embed
exception handling constructs does not introduce hyper-strictness.
It is straightforward to extend the definition of the functions and the
functional forms to support lazy semantics. It is also possible to prove
the algebraic laws of FP with non-strict functions in lines similar to that
given in [1]. We do not present them here as it is beyond the scope of
this paper.
Select
Tail
Atom
Equal
Equal is a strict function, strict on both components of
the argument. So, if the input object X is partially or fully
shielded, then Equal behaves like the identity function Id.
That is,
Null
Reverse
Reverse
Distribute from Left
The function Distribute from right can be defined in a
similar way.
Add, Subtract, Multiply, Divide, And, Or, Not
These functions expect the input object to be of the form
(except the Not function for which the input is of
the form X 1 ) and are strict in both
Transpose
Append Left
Append left is strict on the second component of the
input. That is,
Similarly Append Right function is strict on the first component
of the input.
Next we deal with the functional forms.
Functional Forms
Composition
(f
Construction
Condition
Constant
The constant functional is non-strict over partially and
fully shielded objects. This means,
Apply to all
Insert
Definitions
The definitions of an FP program are written in the form:
where hfunc-namei and hfunc-defni represent the function
name and the function body respectively. The term inside
the braces is optional. This term is included only if the
function raises any exception. The exceptions raised by
the function are listed in exception-list.
Programming Exceptions
A Terminate exception can be raised using the Esc function
and an exception name e. That is,
Adding syntactic sugar, the Esc function can be written in
FP style as Esc ffi [e; Id]. However, we continue to use the
representation Esc e for simplicity sake.
Handler Functions
A handler for a Terminate exception e is written as
(read as 'on e do H'). The application of this function,
called the handler function, on X is defined as:
In order to write handler functions in FP style, a function
Hand can be defined as
However we prefer the for the sake of
simplicity. Further, from the definition of Esc and handler
functions, it can be observed
is any exception name.
Finally, the default handler can be written as
and has the following semantics.
B. Examples
We illustrate the notations introduced so far by means
of a few examples.
Example 3.1
The first example deals with a system-defined exception.
Consider the select function k, to select the kth element of
an object. Let there be a system-defined exception e ISV
where ISV stands for Illegal Selector Value. Further, as-
sume, at runtime, the application of the function k on an
object raises the exception e ISV whenever k
is greater than n. Then in the exceptional case, the application
results in hX
The handler function 1r is the function
to select the rightmost element of a structured object,
can be applied to the shielded object to produce Xn .
Example 3.2
Consider the ADD-SUBEXP function discussed in Section
II-B. The problem can be programmed in FP as:
The application of (ADD-SUBEXP:1) results in
Applying Finally
Add
that the result will be the same irrespective of the order in
which the subexpressions EXP1 and EXP2 are evaluated.
It is interesting to note that in Gerald [9] and PSML [6],
one of the two exceptions e1 or e2 is given a higher priority
and only that exception is allowed to propagate in the
above example. In evaluating subexpressions in parallel,
deterministic behavior is guaranteed in this way in Gerald.
While it is intuitive why such an approach is adopted in
Gerald which is based on the replacement model of Yemini
and Berry [11], it is not obvious in PSML which uses
error data values to handle exceptions. Further, prioritizing
exceptions results in the loss of commutative property.
Commutativity is regained in Gerald by enforcing certain
lexical scoping rules. In any case, enforcing priorities for
subexpressions under parallel execution model would cause
additional implementation overhead. Neither Gerald nor
PSML addresses the implementation issues involved in prioritizing
exceptions.
Example 3.3
Lastly, we consider the conversion of a string of numbers
to their ASCII equivalents. We assume the functions ASC
and ASC$ produce the ASCII equivalent of a number and
the ASCII character '$' respectively. (The conversion of
a string of numbers can easily be done in FP using the
'apply-to-all' functional. But to illustrate the features of
the proposed notation in a recursive context, we program
the example in the following way.)
[ASCII ffi1, ASCII-STRING ffitl]
Functions Ge, Le, and Or represent, respectively, Greater
than or equal, Less than or equal, and logical Or functions.
The application of ASCII-STRING to an input h64; 65; 30i
results in hA; B;
C. Remarks
Certain remarks are in order.
(i) System-defined exceptions are detected implicitly at
runtime. Such exceptions are raised while executing
the primitive functions of FP. So it is appropriate to
declare system-defined exceptions to be of type Termi-
nate. Handlers for system-defined exceptions can easily
be defined using the proposed notations as shown
in Example 3.1.
(ii) In our proposal, the user has the freedom to define
the handler anywhere he or she likes. Shielded objects
(partially or fully) propagate through strict functions
and reach the handler. The propagation is implicit.
However, non-strict functions may have the dangerous
effect of (partially or completely) pruning the exception
object. Hence, care need to be exercised in
placing the handler functions.
(iii) A shielded object propagates through the dynamic invocation
chain until it encounters an appropriate han-
dler. Hence, the handler association is dynamic. It
may be observed that our view of Terminate exceptions
(that they shield abnormal values) facilitates dynamic
handler association in a natural manner.
(iv) As mentioned earlier, PSML and Gerald require additional
prioritizing schemes to retain deterministic behavior
under a parallel execution model. In our ap-
proach, however, an exception object is non-persistent
and does not cause any indeterminate behavior no
matter in which order the subexpressions are evaluated

(v) Lastly, we review the problem of exceptions introducing
hyper-strictness in functional languages. Consider
the function
SIGNALS e1.
The expression
is similar to
handle bad by x.0 terminate in
where the
select function is used in the former in the place of
the operator \Phi. In [9] it has been argued that the
up-propagation of the signal bad transforms \Phi into
a strict function. However, reducing Circled-plus :
which in turn returns
the value 14. Thus, the evaluation remains non-strict
even in the presence of the exception e1 and its
up-propagation. However, if we allow exception objects
to be persistent, then the application of Circled-
plus on h12; 13; 14i would result in 2 : h13 e1 i, making
the select function strict. Thus, we say that it
is essentially the persistent nature of exception ob-
jects, and not the up-propagation, that transforms
non-strict functions into strict functions.
In the following section, we present a formal approach
to describe Terminate exceptions and their handlers.
IV. A Formal Study on FP with Exceptions
A. Preliminaries
The set of input objects, called the input domain, is
denoted by O.
O
In order to study the algebraic properties of functional pro-
grams, first we need to study the behavior of the primitive
functions of FP. For each primitive function f, the domain
of input objects O can be partitioned into two disjoint
sets, called the Active Domain (represented by AD (f))
and the (denoted by ID (f)). Intuitively,
the Active Domain of a function f consists of those objects
on which the function has its intended effect; for objects
belonging to the Identity Domain of f, the function
is inhibited. Formally, an object X belongs to AD (f) if
X. (For the identity function Id, AD
ID (f) is the set of all objects for which
that the objects in the Active Domain of a function could
still be partially or completely shielded objects.
The Active Domain and the Identity Domain of Esc e
are:
As objects belonging to C form
the Domain of Esc e. Next, we consider the handler
function
It may be noted that the effect of the application of a handler
function on an object belonging to its Active Domain is
slightly different from the effect of f : X, for X 2 AD (f).
This is because performs two actions -
(i) removing the shield of X and (ii) the application of H
on the normal object. Barring this small difference, we can
say that any primitive function f (including Esc e functions
and handler functions) behaves either as f or as the
identify function Id. The behavior of f is, however, deterministic
and depends entirely on whether the input object
is in the Active or the Identity Domain of f.
B. The Choice Operator
To represent the behavior of a function mathematically,
we introduce a deterministic choice operator !.
function f can be written as f
where f1 is same as f and f2 is the identify function. The
application of f on an object X results in
AD (f) and
Again, f 1 should be appropriately defined for handler func-
tions. The details of f i are not required for proving the
algebraic properties and hence will be ignored henceforth.
The following axioms can be written on the choice operator
using the definitions of functional forms presented
in Section III-A.
Axiom 1: [Composition]
Axiom 2: [Condition]
Axiom 3: [Construction]
Axiom 4: [Apply-to-all]
Axiom 5: [Insert]
(f in
The basis for the above axioms is that the selection (or
choice) is deterministic and the selection of i in one function
does not influence the selection of i in the other. Therefore,
the choice operator can be rewritten for one or more variables
with the choice subscripts suitably renamed. Lastly,
n; 8X, as the Active Domain for the constant functional
n is O.
C. Algebraic Laws of FP Programs
In this section, we prove some of the algebraic laws of
FP programs listed in [1]. It is important to realize that
the FP programs considered here have been extended to
include exception and handler functions.
Composition is associative:
Composition and Condition:
Proof: The proof of this law is similar to that of L2. 2
Construct and Composition:
L4:
Using Axiom 3,
By Axiom 1,
L5:
Proof: This law can be proved in lines similar to that of
L2 and L4. Axioms 2 and 3 are used in the proof. 2
Construct and Apply-to-all:
Using Axiom 2,
Using Axiom 4,
Miscellaneous:
Proof: Using axioms 1 and 4, this law can be proved. 2
Proof: This law can be proved by using axiom 2 and the
algebraic law
The above laws are by no means exhaustive. One can
easily prove the other laws described in [1] in lines similar
to those discussed above.
V. Resume Exceptions
In this section we introduce the notations for programming
Resume exceptions.
A. Notations
Resume exceptions are denoted by "
e, where e could possibly
be subscripted. The function Res " e is introduced to
raise the Resume exception. The handler H for a Resume
exception is represented as
the influx symbol
indicating that " e is of type Resume. As mentioned
earlier, when the application of a function on an object X
raises a Resume exception, the object X is treated as cur-
able; the corresponding handler function is applied to the
object X at the activation point. If neither a corresponding
handler nor a default handler is present for a Resume
exception, a runtime error occurs when a Res "
e function is
invoked.
Resume exceptions do not shield objects, and the existing
definitions of objects, functions and functional forms
are sufficient to express them. Explicit compile-time techniques
are required to accomplish dynamic association of
handler to a Resume exception. It is beyond the scope of
this paper to discuss an implementation for the association
of handlers.
We now present a simple example to illustrate how Resume
exceptions can be programmed.
Example 5.1
This example deals with a program that adds the magnitudes
of a sequence of numbers. The program calls a
function SUM which adds two numbers. Exceptions are
raised in SUM whenever either of the numbers considered
for addition are negative. The handler takes an input argument
and returns the magnitude of it. The SUM operation
is resumed after handling the exception.
The Negate function negates the input argument. It can
be seen that the COND function in the above example
raises " e whenever its input is negative. The cure function
Negate is immediately applied to the input object when the
exception " e is raised.
B. Remarks
(i) At first sight, functions raising Resume exceptions appear
to violate referential transparency. Consider a
function F which raises a Resume exception "
e. Suppose
H is the handler for "
e, not necessarily associated
with F. Now F:X may result in one of the two values,
depending on whether the object lies in the normal or
exception domain of F. Thus it appears that F is non-
deterministic. But this is not so and can be reasoned
in the following way. The function F can be considered
as a (sort of) higher order function with H as an argu-
ment. The function F selectively applies H whenever
the input object is in the exception domain. That is, F
is a deterministic function whose range can be divided
into two sets, one corresponding to the normal values
and the other to the exception values.
(ii) Resume exceptions can be indirectly used to define
higher order functions in FP. For example, consider a
function F which can be written as a composition of
two functions. That is, let
If we want to define a function F(H) as
F
where H is supplied as an argument, then using the
Resume exception notation such a function can be defined
as
Thus, the function F can be considered to have a place
holder which can be filled by the handler function.
Different handler functions can be associated with F
to generate a number of F(H) functions. This can be
an interesting use of Resume exceptions.
VI. Related Work
There have been a few attempts [2, 3, 6, 7, 9, 10] to
incorporate exception handling in functional or applicative
languages. Here we compare the earlier proposals with
ours.
(i) The main difference between our work and the related
ones is the radical change in the way exceptions are
viewed. Earlier proposals [3, 7] treat exceptions as a
means of effecting a control transfer. This leads to a
fundamental conflict and as a remedy requires the imposition
of sequential execution. We treat exception
objects either as shielded or as requiring immediate
application of cure functions. This approach naturally
suits the functional style and, therefore, does not
necessitate any constraint on the execution model.
(ii) Our approach is similar to PSML [6] in that both
use error data values to handle exceptions. However
in PSML, as explained in Section III-B, deterministic
program behavior is retained by assigning priorities
to exceptions. Besides, prioritizing exceptions
involves additional implementation overheads. Gerald
[9], which uses the replacement model of Yemini
and Berry [11], also prioritizes exceptions to guarantee
deterministic behavior. On the other hand our ap-
proach, by following non-strict semantics, avoids the
need for such requirements.
(iii) In Gerald it has been argued that the up-propagation
of error signals transforms non-strict functions into
strict functions. To overcome this problem, the use
of firewalls and down-propagation has been proposed.
In Section III-C we established that it is the persistent
nature of error signals in Gerald that makes non-strict
functions into strict functions. As shielded objects
are non-persistent, our approach does not introduce
hyper-strictness.
(iv) In our scheme, an exception is automatically propagated
to higher level modules until an appropriate handler
is found. That is, the propagation of an exception
along the dynamic invocation chain is transparent to
the user. The programming language ML [7] also supports
implicit propagation of exceptions; in contrast,
in ALEX [3], the exceptions must be explicitly transmitted

(v) ML [7] supports only Terminate type of exceptions;
whereas our work, like ALEX 2 , allows both Resume
and Terminate exceptions.
(vi) FL language [2] has been designed with constructs for
exception handling. Though user-defined exceptions
can be programmed in FL, exceptions are mainly used
to signal application of inappropriate input objects to
primitive functions. Further, only one type of exception
is allowed in FL.
(vii) Wadler [10] suggests lazy evaluators need no extra constructs
to provide some exception handling - all function
results can be packaged as a singleton list, with
the null list representing the error result. However this
minimalistic approach requires considerable programmer
effort and discipline. Moreover his method does
not support different kinds of named exceptions.
VII. Conclusions
In this paper we have introduced the notations for exception
handling in FP languages for constructing reliable
software. The notations introduced are illustrated with the
help of example programs. In incorporating exception handling
in FP, the conventional view of treating exceptions
as a means of effecting control transfer has been discarded.
Our view of exceptions allows us to describe the semantics
of FP functions in a functional way, retaining referential
transparency and the nice mathematical properties of
functional languages. In fact, this has been accomplished
without imposing additional execution constraints, such as
sequentializing the execution. Further, the semantics of
the primitive functions of FP are defined in a non-strict
manner over the exception objects. This means that even
if eager evaluation strategies are followed in an implemen-
tation, the result will still be lazy over exception objects.
Lastly, our approach to exception handling does not introduce
hyper-strictness.
Even though we chose Backus' FP and incorporated exception
handling constructs in them, our scheme is general
and could be applied to any functional language. As the
In addition, ALEX supports exceptions of a different class called
Retry [3]. For Retry exceptions, after exiting the handler, the execution
control is switched over to the beginning of the module from where
the exception was raised. We do not attempt to incorporate this class of
exceptions because of the inherent control transfer present in them.
proposed method to exception handling has the advantages
of retaining (i) the nice mathematical properties of functional
language, (ii) deterministic program behavior, and
(iii) non-strictness of lazy languages, it will lead to an implementable
parallel programming language.

Acknowledgments

The author is thankful to the anonymous reviewers for
their helpful comments. The work presented in this paper
would not have taken its present shape without the
numerous discussions the author had with R.A. Nicholl,
University of Western Ontario, London, Canada.



--R

"Can programming be liberated from von Neumann approach? A functional style and its algebra of programs,"
"FL language manual,"
"An exception handling construct for functional languages,"
"Exception handling and software fault tolerance,"
"Exception handling: Issues and a proposed notation,"
"Exception handling in a parallel functional lan- guage: PSML,"
"The definition of Standard ML, version 3"
"System structure for software fault tolerance,"
"Ger- ald: An exceptional lazy functional programming language"
"How to replace failure by a list of successes: A method for exception handling, backtracking and pattern matching in lazy functional languages,"
"An axiomatic treatment of exception handling in an expression-oriented language"
--TR
How to replace failure by a list of successes
An axiomatic treatment of exception handling in an expression-oriented language
Can programming be liberated from the von Neumann style?
Exception handling
An Exception Handling Construct for Functional Languages

--CTR
Margaret Burnett , Anurag Agrawal , Pieter van Zee, Exception Handling in the Spreadsheet Paradigm, IEEE Transactions on Software Engineering, v.26 n.10, p.923-942, October 2000
Takeshi Ogasawara , Hideaki Komatsu , Toshio Nakatani, EDO: Exception-directed optimization in java, ACM Transactions on Programming Languages and Systems (TOPLAS), v.28 n.1, p.70-105, January 2006
exception handling;programmer;functional languages;functional programming;high level languages;terminate;referential transparency;input object;programming theory;commutativity properties;implementation restriction;resume