<<

MOPping up Exceptions S. E. Mitchell, A. Burns and A. J. Wellings, Department of Computer Science, University of York, UK

Abstract: This paper describes the development of a model for the reflective treatment of both application and environmentally sourced exceptions. We show how a variety of exception models can be implemented using an exception handler at the metalevel. The approach described allows for better separation of exceptional and normal error-free program code producing systems that are easier to understand and therefore maintain. Keywords: metalevel architecture, reflection, exceptions.

1 Introduction with particular emphasis on the relationship between concurrency and reflective The principle reason for the inclusion of exceptions. Finally, we evaluate the mechanisms in effectiveness of the work with respect to the programming languages is a desire to success of reflection in producing the separate error handling from the programs required separation of concerns. normal operation [Burns and Wellings, 1996]. This is in line with the justification 1.1 Non-reflective Exception Models for the use of reflection in system design – in that its use aids in the separation of The exception model that we explore within concerns. this paper is derived from the common non- reflective one of exceptions being raised Despite this desire for a separation, in many (thrown) and subsequently (possibly) caught approaches the handler code is still within a separate section of code (termed the intermingled with application code, albeit exception handler) usually at the end of an moved to the end of a program block. In this exception block. Exceptions that are not paper we explore the use of reflective caught by any exception handler currently principles to complete the separation of within scope are propagated back up to the concerns by attempting to operate on previous level – the caller – and the search exceptions at the metalevel. for a handler repeated. This model follows The remainder of this introduction describes that used in many current object-oriented the exception model that we have used as and procedural languages such as Ada95 the basis for our work and explores the [Intermetrics, 1995] and ++ [Stroustrup, motivation for producing a reflective 1997]. Both Ada95 and C++ use the treatment of exceptions. The second section termination model of exception handling – describes two variations of the model, the once an exception has been handled the first in Section 2.1 considers a model where exception block is terminated and control the raising of the exception is reified returns to the containing block or caller as whereas Section 2.2 considers a scenario appropriate. The alternative method of where the exception itself is the reified processing is the resumption model where entity. Next Section 3 explores further issues control is returned to the containing block after the exception has been handled. This is language model [Watanabe and Yonezawa, not as common as the termination model and 1988; Maes, 1987] inorder to develop the is not implemented in any ‘mainstream’ most general result. Within this general language. Furthermore, the resumption reflective architecture, the structure and model can be implemented in a number of behaviour of an object is controlled by its flavours – re-execute from the start of the , which itself is controlled by a exception block, re-execute the instruction meta-metaobject. Unlike many reflective which caused the exception or resume object-oriented languages, we allow a base- at the instruction following the level object to have multiple “faulty” instruction. each responsible for some aspect of structure and/or behaviour of the base-level object. Within a program it is possible, and important, to distinguish between two 1.3 Motivation different types of exception depending on their source: Exception handling can be viewed as providing error containment for an object • Environmental – The exception is raised and helps to prevent errors propagation by an entity (e.g. the run-time system) within the system. The issues related to outside the current program due to an exception handling within an object-oriented occurring in the environment context have been considered by a number within which the program is running, for of authors, notably [Miller and Tripathi, example, a floating point error raising the 1997]. However, we are not aware of any CONSTRAINT_ERROR exception in an work that addresses issues related to Ada95 program. reflection and exceptions. In a reflective • Application – The exception was defined system, the metalevel reifies (makes within the program code and is raised as a concrete in terms of actually implementing) result of a program action (or inaction). the abstractions used by the base-level. We For example, an exception raised as the thus view exceptions as implementing the result of a failed application assertion. abstraction of fault-free objects/modules within a system and that using a more In addition, either type of exception can be explicit reflective model would enable us to synchronous or asynchronous. A exploit the further advantages offered by synchronous exception is raised as a direct reflection. These are: result of current program activity, e.g. resource locked, whereas an asynchronous • A strong, disciplined separation of exception is not related to the current concerns – Our initial motivation for program activity though the exception may this work stemmed from a belief that the have been raised as a result of past activity separation of concerns offered by a or current in-activity. Note that for reflective treatment of exceptions could application exceptions the asynchrony can provide a useful extension of their use to be viewed as the insertion of an arbitrary divide functional and error-handling delay between the exception being raised code. In addition, we want to be able to and the subsequently being handled support a wider range of features (e.g. different exception models) than can be 1.2 Model accommodated in a non-reflective Within this paper we aim to produce a language. A reflective system permits an reflective treatment of exceptions and thus effective discipline to be imposed on the follow the usual reflective object-oriented separation since the metalevels can impose the required restraints on change 2.1 Reifying the raising of an within the system. exception • Transparency and self-containment – The first reflective model of exception These refer to the principles that the handling we shall consider uses a base-level is not reliant on the metalevel computational model with two distinct for correct functional behaviour and that entities; objects and exception handlers. An the facilities implemented by the object throws an exception which is metalevel are transparent to the base- subsequently processed by an exceptions level. Viewed from the perspective of an handler. Reflection is used to reify the act of application, facilities reified by the raising/throwing the exception; thus when an metalevel are seen as not relevant to the exception is raised, a jump to the metaobject provision of correct functional operation. occurs that then handles exception through Note that system requirements, e.g. fault the exception handler along with any other tolerance or security, may well be processing undertaken by the metalevel. implemented at the metalevel. However, This procedure is analogous to the if they are not available the application reification of a method call that causes an will still operate except that it would interception of the call to the base-level execute without the safety net of the object with subsequent processing controlled fault-tolerance or security layers by the metaobject. insulating the application from an unreliable insecure execution environment. • Recursive – The metalevel reifies abstractions used at the base level and L E

the recursive nature of the reflective V E Metaobject Metaobject L

A ‚ model means that the meta-metalevel T E ƒ reifies abstractions used at the metalevel. M ê L E

This principle means that we seek V  E L E

consistency of S å A entities at each meta-level. B Exception Baselevel Baselevel handler object B object A 2 Exceptions and Reflection This section describes the development of Figure 1: Exception our first model of reflective exceptions. The handling with reified basic principle of operation is that the act of exception raise. raising of an exception becomes a reified Figure 1 illustrates how an exception is operation. After briefly presenting the model raised and handled within this system. The we will discuss why such an approach is not flow of control proceeds as follows: adequate and show how the basic model can 1. Base-level object “A” invokes a method be changed to enhance the separation in “B”. The invocation is trapped by the between functional and exceptional code. metalevel. 2. The metaobject invokes an appropriate method in the base class in response to the invocation request from “A”. 3. At some point an exception is raised 2.1.1 Exception Propagation which, since this is a reified operation, causes a jump to metaobject If the exception cannot be processed (e.g. computation. there is no handler present) then the metaobject must propagate the exception to 4. The metaobject invokes the selected the invoker’s meta-object with possible handler which may access/modify the subsequent termination of the method state of “B” to resolve the exception. invocation that raised the exception. The call The handler returns information to the to the base-level object which actually raised metaobject indicating the success or the exception should be terminated otherwise of the exception handling. irrespective of the exception termination 5. The metaobject decides on the fate of the model currently in use – after propagation, method invocation request from “A”. In even for the resumption case, the invoker this example it terminates the original object is the one to be resumed. This model call at point ƒ (indicated by the line is illustrated in Figure 2. crossing the invocation arrow).

‚ ƒ L E V

E Metaobject Metaobject Metaobject L A T E

M ê L E

V  E L E

S å A å

B Exception Baselevel Baselevel Baselevel handler object C object B object A

Figure 2: Termination model using reified exception raise.

As in Figure 1, the base-level object “A” no handler associated with ÆB and so the invokes “B” (å) through metaobject ÆB, exception is propgated again to ÆA (ƒ) and but in this example the method at the base- the call to “B” terminated. In ÆA there is level then invokes “C” through ÆC (also also no handler – and nowhere to propagate labelled å). The method invoked by ÆC in to – and so the program must also terminate the base-level object raises an exception (ê) with an “Unhandled Exception” error. and the reification of the raise causes The model can readily be adapted to the processing to proceed in the metaobject. The non-termination case by a change in exception handler selected by the metaobject semantics of the metaobject which causes fails to handle the exception so the method control to return to base-level object B, at invocation in the base-level object is the point where the call to object C occurred, terminated by the metaobject () and the after the exception has been handled by the exception propagated to ÆB (‚). There is metaobject. One may also need to change the behaviour of application object B to retry the base-level from executing its current the operation perhaps using a replicated task, however, since this is dependent on the object C. An important advantage over semantics defined at the meta-level this is a conventional exception mechanisms is that design option. Certain classes of AEE, such the metaobject controls the behaviour and as the garbage collection exception, may syntax of the base level. Thus the metalevel never require the base-level to be halted exception handler can modify the base level whereas others may require interruption and (e.g. change the base-level state) before a subsequent change in the flow of control at returning control and thus prevent the the base-level. Note that even if the model is exception being re-raised. such that the base level is interrupted when an environmental exception occurs, the base If a handler for a synchronous application level may subsequently be resumed without exception does not exist within the any changes after the exception has been metaobject, the propagation continues at the processed or alternatively, a whole section metalevel, a process that is illustrated in the of the program may be abandoned. figure above. If no handler is found at the caller’s metaobject then that method As an example of how AEEs might interact invocation is also terminated and the with the meta-level, consider a base-level propagation repeated. object that makes a non-blocking attempt to access a resource (e.g. communication 2.1.2 Environmental Exceptions channel). At the point where the attempt is made the resource is unavailable and so a The class of exceptions that can be raised by 1 entities outside the current program are said future is returned to the base-level. Whilst to have an environmental cause. This section the base-level continues processing, the is split into two subsections dealing with environment raises an AEE in all meta-level asynchronous and synchronous objects that results in the freeing of the environmental exceptions respectively. resource from another object. A further AEE is raised in the base-level object’s meta- 2.1.2.1 Asynchronous Environmental object which allocates the resource to the Exceptions future assigned to the base-level. When the An asynchronous environment exception base-level attempts to access the future it (AEE) is raised as a result of an event can use the resource without ever being external to the program and not as a direct aware of meta-programs allocation attempts. result of current program activity (though it 2.1.2.2 Synchronous Environmental may be raised as a result of current program Exceptions inactivity). As examples, a run-time system may raise a garbage “low memory” Synchronous environmental exceptions are exception to cause each object in the system exceptions that are raised by the to release resources or a health monitor may that a patient requires immediate 1 A future is reference to a resource that is returned to attention. a program by the run-time system when the resource Within our model, AEEs are raised is not immediately available. It enables the requesting program to continue to perform work whilst waiting immediately at the metalevel without being for the resource to become available. If the future is reified entities from the base-level. Since sticky then further attempts to access the contents reflective components may process in before the resource is available will cause the parallel with the base-level components then program to block pending allocation otherwise access there is no fundamental requirement to stop attempts result in a further ‘not-available’ indication environment as a result of current program error recovery. This may be useful for activity and so may require handling in exceptions for which no state restoration different manner to asynchronous is required in the base-level object or a environmental exceptions. fast response is required. A synchronous environmental exception is 2. Restore the base-level object’s state (e.g. raised by an external entity as a result of through roll-back) and attempt re- actions or in-actions taken by the current invocation of the method. If the program. In this manner we can consider an subsequent invocation goes to a different environmental exception as a hidden method then the handler has effectively program assertion in that if the exception is implemented an acceptance block. raised then the assertion can be said to have 3. Abandon the method invocation and failed. Since these exceptions are raised as a delegate subsequent handling of the result of evaluating the hidden assertion it is invocation that caused the exception to a clear that the exception be raised by the replicated instance of the base-level environment at the base-level and then object whilst, in parallel, restoring the treated as a synchronous application now faulty primary. exception (i.e. reified and then handled at the meta-level). After the exception has been The decision as to which action to pursue handled the system will then terminate the need not be fixed – the metaobject can exception block or resumes execution examine the system self-representation to according to the particular exception model. determine the optimal method of exception handler. This run-time dynamism can extend 2.1.3 Discussion to the modification of handler by metalevel By the simple act of moving the control of to process new exceptions or existing exception handling to the metalevel confers exceptions in new ways. The use of run-time a major advantage over a conventional, non- reflection means that change in the system reflective, model. Significantly, it enables can occur dynamically at any point, the metaobject to perform work both pre- however, within a reflective system the and post- handler execution – for example to disciplined “opening up” of the run-time check that an exception handler has system means that the system designer can performed correctly and that object constrain change to occur only at specified invariants hold after its execution. Such points. Restricting the reflection mode to checks can then be applied to all exceptions constrains the degree of raised in the object providing obvious change that can be applied to a system and advantages of single point of control. thus permits only re-configuration when the system is built. The choice of handler for a particular exception is made at run-time and can vary Unfortunately, this model does not enable a both from object to object and also during simple change from the resumption to program execution. In addition the action termination exception models since the taken by the metaobject after an exception application will have been programmed with has been raised but prior to invoking a certain assumptions in mind. These particular handler can vary, for example it assumptions cannot be changed by simply could: altering how exceptions are handled – one must also alter how the exception handler 1. Return the exception to the caller behaves and how the calling program without attempting further processing or behaves. Whilst changing the base-level program to reflect these changed thus the system designer easily alter the error assumptions is entirely possible within a treatment semantics) and enables different reflective system is constitutes a major cost. metaobjects to share exception code. However the third approach is in fact 2.1.3.1 Location of Exception handler equally flexible since reflection allows both Within this system, the exception (i.e. the the syntax and behaviour of the metaobject point where an exception is raised and the (in this case, the structure and behaviour of exception handlers) are located at the base- the embedded exception handler) to be level but the exception control is located at modified through method invocation in the the metalevel. Thus we have only achieved a meta-metalevel. limited separation of concerns since both However, the fourth scheme enables us to handlers and functional objects exist at the combine the advantages of separate handlers same level and only the exception control without introducing new language entities has been reified. Also we have been forced through the use of an alternative exception to introduce a new language entity, the architecture where the exception itself is exception handler which further weakens reified and responsible for its own handling. our aim of developing a fully recursive We thus consider this to be the most model. promising and is the subject of the next Recall that our principle aspiration was to section. make the separation of functional code and error code more explicit, and therefore we 2.2 Reifying Exceptions surmise that moving the location of the The previous section considered how to map exception handler(s) to the metalevel will the common exception models into a enable us to enhance the separation of reflective framework through the reification concerns. However this leaves open whether of the raising of the exception. As a result, the exception handler should be: the clear separation of functional and 1. Integrated as part of the base-level object exceptional code was compromised with a and invoked by the metaobject, mixing of responsibilities between base and metalevels. This section explores the use of 2. Located in separate object at the an alternative architecture where the metalevel (though not itself a exception itself controls the handling and metaobject) to which exception handling will enable the metaobject to modify the is delegated by the metaobject, exception prior to handling or propagation. 3. Located as part of the base-level object’s We will show how this architecture metaobject, produces a more disciplined separation without introducing any new entities into the 4. An alternative architecture which does computational model. not use ‘exception handlers’ as they are commonly known. First consider that an exception is an object (as in, for example, C++) with the extension The first approach is identical to the one that this object is reified and therefore has a described above and would therefore suffer associated metaobject. Thus when an from the same problems regarding lack of exception object is created, a jump to transparency and separation of concerns. metalevel processing will occur. This is in The second is appealing since it is highly contrast to the previous discussion where the flexible (for example, the destination of the act of raising the exception was reified and delegation can be changed at run-time and therefore caused the jump to metalevel processing. We shall term the metaobject associated with each exception object when meta- Exception exception it is created (that is raised) the handler metaexception object. object L E V

The role of the exception object is not only E Metaobject L A to provide the link to the metalevel but also T E to maintain state about the exception which M L E is not part of the base-level object’s state. V E L E

Note that the latter may well be S assertion/ A Baselevel B exception replaced/modified by exception handler and object thus we need a place to retain information object during the exception handling. Within this model we view the base-level’s computation as follows; the point where an Figure 3: Object diagram exception can be raised is considered to be a for the raising of a reified program assertion which will be true when exception. executed. If the assertion fails, i.e. is false, The metaexception object operates in then the reification process causes the exactly the same way as any reified metalevel to take whatever action is required metalevel entity in that it controls both the to make the assertion evaluate to true. From structure and behaviour of the exception at the applications viewpoint the assertions are the base level. When an exception is raised, always true. This approach maintains the an exception object is instantiated with an transparency requirement – if the base-level appropriate metaexception object. The is running without metalevel support then it metaobject is then responsible for managing will continue as long as assertions are true exception resolution or propagation. This and will simply not benefit from corrective process is illustrated in Figure 4. actions.

ñ

meta- ‚ Exception Exception exception handler handler object ƒ L E V

E Metaobject Metaobject L A T E ƒ M L E

V  E L E

S ê å A

B exception Baselevel Baselevel object raise/ object B object A creates

Figure 4: Exception handling and propagation with reified exceptions Figure 4 shows a complete flow of control the ongoing method call is terminated by for reified exception handling using the the metaobject. termination model. The six stages are as 6. The metaexception object repeats the follows: attempt to handle the exception with the 1. Base level object A invokes a method in handler(s) at the onvoking metaobject. object B. The message receipt is If, after all possible propagation attempts intercepted by the metaobject. have occurred the exception remains unprocessed then the metaexception 2. The metaobject invokes the requisite object is responsible for handling and method script. may terminate the program. 3. An assertion fails and an exception This change enables us to take the model object is created. The executing method described in previous sections and extend it script blocks. The exception object by allowing the exception to control its creation is reified and so control passes future. For example, a system could be to the metalevel metaexception object. created in which raised exceptions are by 4. The metaexception object controls the default bound to a metaexception object that semantics of exception handling. In this implemented the termination model. case it invokes routines in a handler in However, at run-time when an exception is the metaobject. The handler(s) at the raised it may prove possible to successfully metalevel have full access to the state of handle of the cause of the exception (e.g. re- the baselevel object through the issue a prompt to receive further input from reflective self-representation and so can the user) and thus the metalevel exception attempt to rectify the cause the of the handler could invoke methods in the exception before returning control. The metaexception object to change the metaexception object has access to any semantics to implement the resumption state stored in the exception object. Note model. Should the system designer wish to that since the metaobject can execute in prohibit such change for a particular parallel with the base level object it can exception or class of exceptions then it is a continue to process information even simple matter of binding to a different though the latter is blocked after creating metaobject which will not accept such the exception object. invocations and so does not permit the After an exception has been successfully semantics to change. handled control is returned to the object The metaexception object is responsible for that created the exception object. Since the controlling the handling of the exception the metalevel will have altered the object object either through delegation to a separate state to resolve the problem continued handler (e.g. one located in the metaobject execution will not immediately result in as in the figures above) or through its own repetition of the error. methods if no handler can be found. 5. However, in this case the exception 2.2.1 Discussion cannot be processed and the handler returns a failure message to the The approach of reifying exceptions metaexception object along with a provides the full and complete separation of reference to the invoking concerns that we were seeking. It is also a object/metaobject pair. Simultaneously, very flexible model – one can change the exception handling semantics at run-time and this can be on a per-exception basis so program will proceed (in the absence of that different exceptions raised by the same errors) in the same fashion with or without object can have different semantics. The the metalevel. desired separation of concerns arises Another significant advantage is that, unlike because both exceptional and functional the previous model, the reification of the code are completely orthogonal – the latter exceptions itself makes possible the exists at the base-level where as the handling of exceptions raised as a result exception code exists at the metalevel and invocations where the caller is a non-reified manipulates the reflective self-representation object (i.e. it does not have a metaobject). of the base-level. With the previous model we needed to make This approach has the advantage of these a special case since no metaobject was introducing no new language or conceptual available to continue the propagation. entities into the system since exceptions are However, the actions in this model are base level objects whose semantics are controlled by the metaexception object handled by meta-level entities. The handlers which can unwind the call chain through for exceptions are simply methods of the both objects and metaobjects until a suitable metalevel object which are manipulated by handler is found. the meta-metalevel to change either the We retain the benefit of multiple exception semantics of how exceptions are handled handlers (since the metaexception object can (e.g. termination or resumption) or to change invoke any present handler in the the actions necessary to recover from an metaobject) and also promote the re-use of exceptional state. Such a high degree of run- handlers. Handlers can be re-used (that is time flexibility is necessary since we want imported from other metaobjects) by the the model to be able to handle exceptions for meta-level and this is of particular any methods which are created at run-time significance where we have a hierarchy of and thus we need to be able to insert new exceptions since the handler will may only handlers or modify existing ones on the fly. need to be written once and automatically From a metalevel viewpoint, one can view imported as the “default” handler by the exception handlers as minimal recovery metalevel without further intervention by the blocks – simple sections of code to restore system designer. the state of an object to a valid state – and that the metalevel then decides what action 3 Concurrency to take; invoke a replica, repeat the operations etc. Such a system would then 3.1 The Concurrency Model produce an exception model similar to that We have adopted a concurrency model in Eiffel [Meyer, 1992] for exceptions raised based around active objects as we feel that as a result of a failed pre- or post-condition. such a scheme has both practical In Eiffel, after an exception handler has applications as well as fitting naturally restored the state of an object it can redirect within a reflective framework. Each active the exception using a “retry” statement. object possesses one or more embedded The model as described is, of course, fully threads that are created when the object is recursive in that exceptions created at the created and execute independently. meta-level will have meta-meta-level objects Consequently, all objects within a system that control their semantics. Thus it fits with (whether active or passive) are multi- the recursive reflective computational threaded and thus require synchronisation to model. It is also transparent – the base-level constrain access to shared data. Similar models have been adopted by a number of The above model is derived from the concurrent object-oriented languages, for concurrency model used in TAO, however, example, TAO [Mitchell and Wellings, in adopting this model we do not intend to 1996; Mitchell, 1995]. limit the applicability of our work and The model of reflective object-oriented consider that our results can be usefully used system permits objects to have multiple with a wide range of concurrency models. metaobejcts and to delegate aspects of the For example the Ada95 model has a “task” control of their behaviour or state to construct which is separate from objects and different metaobjects. We use distinct in such a case metaobjects and metatasks metaobjects to separate the metacontrol of would also be separate entities rather than concurrency from the normal metacontrol of embedded within the same object. an object into a metatask object. This object 3.2 Reflective Exceptions and controls the behaviour of the Concurrency embedded in the base-level object and is also responsible for initiating thread Within a concurrent computational model execution and implementing context which uses either an active object model or a switches. task based model, the threads can operate independently of any ongoing method calls. In keeping with the design of the base-level Thus it is not necessary to terminate object that contains an embedded thread to embedded threads when an exception cannot form the active object, the controlling be handled within the metaobject. However, metatask object is embedded within the the exception handler at the metalevel will relevant metaobject. This model is need to co-operate with the metatask when illustrated in Figure 5 shows a single base- an exception is raised by a base-level task. level and metalevel object pair with arrows showing the actions of the metatask, namely, When a base-level tasks raises an exception, the initial start of thread execution, one or an attempt must be made, as described more context switches and finally the thread above, to handle it within the metaobject. termination. Should this exception handling be successful, the task may be able to resume or it may be necessary for the metaobject to Metatask L Metaobject

E cause the metatask to recreate the task (if the V E

L raising of the exception had caused it to be A T E

M terminated) or to cause a context switch to

L resume the task (resumption model) at the E V E

L appropriate point. E S A B Baselevel However, perhaps the more interesting case object occurs when the metalevel cannot handle the exception. In this case the task must be Figure 5: Illustration of the terminated – again through cooperation with concurrency model of objects with the metatask object. Embedded threads embedded threads and within an active object are created along metaobjects with embedded with the active object and thus are directly to metatasks. The metatask controls analogous to the main thread of control in thread creation, context switch many programming languages. and termination. Consequently there is no sensible place to propagate the exception to, and like a main program, the active object must now be altered or split into several different considered fatally flawed and terminated. It handlers. passing is marked, however, by an Within our system, the flexibility arises asynchronous application exception being because the metalevel exception handler has raised in the object which created the active its syntax and semantics defined at the meta- object which will allow it to take appropriate metalevel. This means the designer of the action to correct the error (re-create the system can control the changes permitted at object perhaps trying a different run-time and thus produce anything from a implementation to avoid repetition of the static system fixed at compile time to a fully exception). Note that due to the autonomous flexible, but inherently less predictable operation of parent and child active objects, system, that can be changed at will to reflect the parent active object may no longer exist the current environment the program finds in which case we need to raise the itself in. A reflective treatment of exceptions “notification of termination” exception also produces a very adaptable system since within the grandparent object and thus the specification of the semantics of the require a run-time system which tracks task exception handling is separated from the creation hierarchies. handler itself. The system described in this paper can covers both the termination and 4 Summary and Evaluation non-termination models for both This paper has explored how the synchronous and asynchronous exceptions implementation of both synchronous and whether application or environmentally asynchronous environmental and application sourced. The semantics of exception are not exceptions can be programmed at the necessarily fixed according to the whims of metalevel. This section presents an overall the programming language, designers are evaluation of the advantages of a reflective free to adapted to suit the needs of a approach to exceptions and also a final particular program. summary and suggestion for future work. This flexibility and adaptability means that Note that many of the points discussed in different components of a system can have this evaluation apply to either of the different approaches to how exceptions are reflective models discussed in this paper. handled and can potentially swap amongst The foremost advantage is that the reflective them at run-time. If such freedom is exception mechanism is extremely flexible undesirable since it would lead to a too and adaptive. In [Miller and Tripathi, 1997] unpredictable system, the designer is able to the authors devise three categories of control the degree of change allowed by evolution of exception; Exception evolution appropriate programming of the meta-levels. (raising new exceptions derived from ones Furthermore, by reifying exceptions, rather already in the ), Function evolution than the raising of the exception, one can (raising entirely new exceptions not permit more localised control over the future currently in the interface) and mechanism course of the exception and also change the evolution (a change in implementation semantics of exception handling whilst it is leading to exception overloading). A being processed. The reified exception reflective system is ideal suited to model is highly expressive as illustrated by overcoming these problems due to its in- the fact that we can easily implement a wide built mechanisms for introspection and range of exception models including those in modification which means that new handlers the mainstream languages C++, Ada 95 and can be added, the semantics of existing ones Eiffel. The model is also highly flexible in that the metalevel program that handles the Programming Languages, Second ed: exception can manipulate the behaviour of Addison-Wesley, 1996. the base-level program. Using this [Intermetrics, 1995] Intermetrics, “Ada mechanism the reflective layer can modify Reference Manual,” ISO/IEC 8652:1995, the base level after an exception has 1995. occurred to prevent it being re-raised – for example, by forcing the base-level program [Stroustrup, 1997] B. Stroustrup, The C++ down a different branch in an acceptance Programming Language, Third ed: block. Addison-Wesley, 1997. Finally, a reflective treatment of exceptions [Watanabe and Yonezawa, 1988] T. has achieved our primary goal of further Watanabe and A. Yonezawa, “Reflection in enforcing a clear separation of concerns – an Object-Oriented Concurrent Language,” there is no mixing of the exception handlers ACM SIGPLAN Notices - Proceedings of in with normal “functional” program code. OOPSLA'88, (23)11, pp. 306-315, 1988. This paper has shown that even a simple [Maes, 1987] P. Maes, “Concepts and reflective approach where exception control Experiments in Computational Reflection,” occurs at the metalevel confers a number of ACM SIGPLAN Notices - Proceedings of advantages. However, we have also shown OOPSLA'87, (22)12, pp. 147-155, 1987. that extending this model so that both exception control and handling occurs at the [Miller and Tripathi, 1997] R. Miller and A. metalevel and that the base-level simply Tripathi, “Issues with Exception Handling in views exceptions as assertions can simplify Object-Oriented Systems,” in Proceedings programs through ensuring a strong, of ECOOP'97, vol. LNCS-1241, M. Askit disciplined, separation of functional and and S. Matsuoka, Eds. Jyväskylä, Finland: exceptional concerns. Springer-Verlag, 1997, pp. 85-103. [Meyer, 1992] B. Meyer, Eiffel: The 4.1 Acknowledgements Language: Prentice Hall, 1992. This work has been done as part of the [Mitchell and Wellings, 1996] S. E. Design for Validation (DeVa) project, Mitchell and A. J. Wellings, ESPRIT long-term research project 20072. “Synchronisation, Concurrent Object- We would like to acknowledge the Oriented Programming and the Inheritance contributions that other members of the Anomaly,” Computer Languages, (22)1, pp. DeVa project have made towards this work, 15-26, 1996. especially for the comments on the work during its various stages of preparation. [Mitchell, 1995] S. E. Mitchell, "TAO - A Special thanks must go to Dr. A. Model for the Integration of Concurrency Romanovsky for the many discussions on and Synchronisation in Object-Oriented exceptions and to Dr. R. J. Stroud for the Programming", PhD Thesis, Department of helpful insights into the principles of Computer Science, University of York, UK, reflection. YCST-95-009, available through FTP from "ftp://ftp.cs.york.ac.uk/reports", 1995. 5 References

[Burns and Wellings, 1996] A. Burns and A. Wellings, Real-Time Systems and