Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/andrew_beach_MMath/features.tex

    r93d0ed3 rf42a6b8  
    1616throw/catch as a particular kind of raise/handle.
    1717These are the two parts that the user writes and may
    18 be the only two pieces of the EHM that have any syntax in a language.
     18be the only two pieces of the EHM that have any syntax in the language.
    1919
    2020\paragraph{Raise}
    21 The raise is the starting point for exception handling
    22 by raising an exception, which passes it to
     21The raise is the starting point for exception handling. It marks the beginning
     22of exception handling by raising an exception, which passes it to
    2323the EHM.
    2424
    2525Some well known examples include the @throw@ statements of \Cpp and Java and
    26 the \code{Python}{raise} statement of Python. In real systems, a raise may
    27 perform some other work (such as memory management) but for the
     26the \code{Python}{raise} statement from Python. In real systems a raise may
     27preform some other work (such as memory management) but for the
    2828purposes of this overview that can be ignored.
    2929
    3030\paragraph{Handle}
    31 The primary purpose of an EHM is to run some user code to handle a raised
    32 exception. This code is given, with some other information, in a handler.
     31The purpose of most exception operations is to run some user code to handle
     32that exception. This code is given, with some other information, in a handler.
    3333
    3434A handler has three common features: the previously mentioned user code, a
    35 region of code it guards, and an exception label/condition that matches
    36 the raised exception.
     35region of code they guard and an exception label/condition that matches
     36certain exceptions.
    3737Only raises inside the guarded region and raising exceptions that match the
    3838label can be handled by a given handler.
    3939If multiple handlers could can handle an exception,
    40 EHMs define a rule to pick one, such as ``best match" or ``first found".
     40EHMs will define a rule to pick one, such as ``best match" or ``first found".
    4141
    4242The @try@ statements of \Cpp, Java and Python are common examples. All three
    43 show the common features of guarded region, raise, matching and handler.
    44 \begin{cfa}
    45 try {                           // guarded region
    46         ...     
    47         throw exception;        // raise
    48         ...     
    49 } catch( exception ) {  // matching condition, with exception label
    50         ...                             // handler code
    51 }
    52 \end{cfa}
     43also show another common feature of handlers, they are grouped by the guarded
     44region.
    5345
    5446\subsection{Propagation}
    5547After an exception is raised comes what is usually the biggest step for the
    56 EHM: finding and setting up the handler for execution. The propagation from raise to
     48EHM: finding and setting up the handler. The propagation from raise to
    5749handler can be broken up into three different tasks: searching for a handler,
    5850matching against the handler and installing the handler.
     
    6052\paragraph{Searching}
    6153The EHM begins by searching for handlers that might be used to handle
    62 the exception. The search is restricted to
    63 handlers that have the raise site in their guarded
     54the exception. Searching is usually independent of the exception that was
     55thrown as it looks for handlers that have the raise site in their guarded
    6456region.
    6557The search includes handlers in the current function, as well as any in
     
    6759
    6860\paragraph{Matching}
    69 Each handler found is matched with the raised exception. The exception
    70 label defines a condition that is used with the exception and decides if
     61Each handler found has to be matched with the raised exception. The exception
     62label defines a condition that is used with exception and decides if
    7163there is a match or not.
     64
    7265In languages where the first match is used, this step is intertwined with
    73 searching; a match check is performed immediately after the search finds
    74 a handler.
     66searching; a match check is preformed immediately after the search finds
     67a possible handler.
    7568
    7669\paragraph{Installing}
    77 After a handler is chosen, it must be made ready to run.
     70After a handler is chosen it must be made ready to run.
    7871The implementation can vary widely to fit with the rest of the
    7972design of the EHM. The installation step might be trivial or it could be
     
    8275
    8376If a matching handler is not guaranteed to be found, the EHM needs a
    84 different course of action for this case.
     77different course of action for the case where no handler matches.
    8578This situation only occurs with unchecked exceptions as checked exceptions
    86 (such as in Java) are guaranteed to find a matching handler.
    87 The unhandled action is usually very general, such as aborting the program.
     79(such as in Java) can make the guarantee.
     80This unhandled action is usually very general, such as aborting the program.
    8881
    8982\paragraph{Hierarchy}
     
    9285exception hierarchy is a natural extension of the object hierarchy.
    9386
    94 Consider the following exception hierarchy:
     87Consider the following hierarchy of exceptions:
    9588\begin{center}
    9689\input{exception-hierarchy}
    9790\end{center}
     91
    9892A handler labeled with any given exception can handle exceptions of that
    9993type or any child type of that exception. The root of the exception hierarchy
    100 (here \code{C}{exception}) acts as a catch-all, leaf types catch single types,
     94(here \code{C}{exception}) acts as a catch-all, leaf types catch single types
    10195and the exceptions in the middle can be used to catch different groups of
    10296related exceptions.
    10397
    10498This system has some notable advantages, such as multiple levels of grouping,
    105 the ability for libraries to add new exception types, and the isolation
     99the ability for libraries to add new exception types and the isolation
    106100between different sub-hierarchies.
    107101This design is used in \CFA even though it is not a object-orientated
     
    116110is usually set up to do most of the work.
    117111
    118 The EHM can return control to many different places, where
     112The EHM can return control to many different places,
    119113the most common are after the handler definition (termination)
    120114and after the raise (resumption).
     
    123117For effective exception handling, additional information is often passed
    124118from the raise to the handler and back again.
    125 So far, only communication of the exception's identity is covered.
    126 A common communication method for passing more information is putting fields into the exception instance
     119So far only communication of the exceptions' identity has been covered.
     120A common communication method is putting fields into the exception instance
    127121and giving the handler access to them.
    128 Using reference fields pointing to data at the raise location allows data to be
     122Passing the exception by reference instead of by value can allow data to be
    129123passed in both directions.
    130124
    131125\section{Virtuals}
    132 \label{s:Virtuals}
    133126Virtual types and casts are not part of \CFA's EHM nor are they required for
    134 an EHM.
    135 However, one of the best ways to support an exception hierarchy
     127any EHM.
     128However, it is one of the best ways to support an exception hierarchy
    136129is via a virtual hierarchy and dispatch system.
    137 Ideally, the virtual system should have been part of \CFA before the work
     130
     131Ideally, the virtual system would have been part of \CFA before the work
    138132on exception handling began, but unfortunately it was not.
    139133Hence, only the features and framework needed for the EHM were
    140 designed and implemented for this thesis. Other features were considered to ensure that
     134designed and implemented. Other features were considered to ensure that
    141135the structure could accommodate other desirable features in the future
    142 but are not implemented.
    143 The rest of this section only discusses the implemented subset of the
    144 virtual-system design.
     136but they were not implemented.
     137The rest of this section will only discuss the implemented subset of the
     138virtual system design.
    145139
    146140The virtual system supports multiple ``trees" of types. Each tree is
     
    149143number of children.
    150144Any type that belongs to any of these trees is called a virtual type.
    151 For example, the following hypothetical syntax creates two virtual-type trees.
    152 \begin{flushleft}
    153 \lstDeleteShortInline@
    154 \begin{tabular}{@{\hspace{20pt}}l@{\hspace{20pt}}l}
    155 \begin{cfa}
    156 vtype V0, V1(V0), V2(V0);
    157 vtype W0, W1(W0), W2(W1);
    158 \end{cfa}
    159 &
    160 \raisebox{-0.6\totalheight}{\input{vtable}}
    161 \end{tabular}
    162 \lstMakeShortInline@
    163 \end{flushleft}
     145
    164146% A type's ancestors are its parent and its parent's ancestors.
    165147% The root type has no ancestors.
    166148% A type's descendants are its children and its children's descendants.
    167 Every virtual type (tree node) has a pointer to a virtual table with a unique
    168 @Id@ and a list of virtual members (see \autoref{s:VirtualSystem} for
    169 details). Children inherit their parent's list of virtual members but may add
    170 and/or replace members.  For example,
    171 \begin{cfa}
    172 vtable W0 | { int ?<?( int, int ); int ?+?( int, int ); }
    173 vtable W1 | { int ?+?( int, int ); int w, int ?-?( int, int ); }
    174 \end{cfa}
    175 creates a virtual table for @W0@ initialized with the matching @<@ and @+@
    176 operations visible at this declaration context.  Similarly, @W1@ is initialized
    177 with @<@ from inheritance with @W0@, @+@ is replaced, and @-@ is added, where
    178 both operations are matched at this declaration context. It is important to
    179 note that these are virtual members, not virtual methods of object-orientated
    180 programming, and can be of any type. Finally, trait names can be used to
    181 specify the list of virtual members.
    182 
    183 \PAB{Need to look at these when done.
     149
     150Every virtual type also has a list of virtual members. Children inherit
     151their parent's list of virtual members but may add new members to it.
     152It is important to note that these are virtual members, not virtual methods
     153of object-orientated programming, and can be of any type.
    184154
    185155\CFA still supports virtual methods as a special case of virtual members.
     
    189159as if it were a method.
    190160\todo{Clarify (with an example) virtual methods.}
    191 }%
     161
     162Each virtual type has a unique id.
     163This id and all the virtual members are combined
     164into a virtual table type. Each virtual type has a pointer to a virtual table
     165as a hidden field.
     166\todo{Might need a diagram for virtual structure.}
    192167
    193168Up until this point the virtual system is similar to ones found in
    194 object-orientated languages but this is where \CFA diverges. Objects encapsulate a
    195 single set of methods in each type, universally across the entire program,
    196 and indeed all programs that use that type definition. Even if a type inherits and adds methods, it still encapsulate a
    197 single set of methods. In this sense,
    198 object-oriented types are ``closed" and cannot be altered.
    199 
    200 In \CFA, types do not encapsulate any code. Traits are local for each function and
    201 types can satisfy a local trait, stop satisfying it or, satisfy the same
    202 trait in a different way at any lexical location in the program where a function is call.
    203 In this sense, the set of functions/variables that satisfy a trait for a type is ``open" as the set can change at every call site.
     169object-orientated languages but this where \CFA diverges. Objects encapsulate a
     170single set of behaviours in each type, universally across the entire program,
     171and indeed all programs that use that type definition. In this sense, the
     172types are ``closed" and cannot be altered.
     173
     174In \CFA, types do not encapsulate any behaviour. Traits are local and
     175types can begin to satisfy a trait, stop satisfying a trait or satisfy the same
     176trait in a different way at any lexical location in the program.
     177In this sense, they are ``open" as they can change at any time.
    204178This capability means it is impossible to pick a single set of functions
    205 that represent a type's implementation across a program.
     179that represent the type's implementation across the program.
    206180
    207181\CFA side-steps this issue by not having a single virtual table for each
    208182type. A user can define virtual tables that are filled in at their
    209183declaration and given a name. Anywhere that name is visible, even if it is
    210 defined locally inside a function \PAB{What does this mean? (although that means it does not have a
    211 static lifetime)}, it can be used.
     184defined locally inside a function (although that means it does not have a
     185static lifetime), it can be used.
    212186Specifically, a virtual type is ``bound" to a virtual table that
    213187sets the virtual members for that object. The virtual members can be accessed
     
    247221completing the virtual system). The imaginary assertions would probably come
    248222from a trait defined by the virtual system, and state that the exception type
    249 is a virtual type, is a descendant of @exception_t@ (the base exception type),
     223is a virtual type, is a descendant of @exception_t@ (the base exception type)
    250224and note its virtual table type.
    251225
     
    267241\end{cfa}
    268242Both traits ensure a pair of types are an exception type, its virtual table
    269 type,
     243type
    270244and defines one of the two default handlers. The default handlers are used
    271245as fallbacks and are discussed in detail in \vref{s:ExceptionHandling}.
     
    276250facing way. So these three macros are provided to wrap these traits to
    277251simplify referring to the names:
    278 @IS_EXCEPTION@, @IS_TERMINATION_EXCEPTION@, and @IS_RESUMPTION_EXCEPTION@.
     252@IS_EXCEPTION@, @IS_TERMINATION_EXCEPTION@ and @IS_RESUMPTION_EXCEPTION@.
    279253
    280254All three take one or two arguments. The first argument is the name of the
     
    298272\CFA provides two kinds of exception handling: termination and resumption.
    299273These twin operations are the core of \CFA's exception handling mechanism.
    300 This section covers the general patterns shared by the two operations and
    301 then goes on to cover the details of each individual operation.
     274This section will cover the general patterns shared by the two operations and
     275then go on to cover the details each individual operation.
    302276
    303277Both operations follow the same set of steps.
    304 First, a user raises an exception.
    305 Second, the exception propagates up the stack.
    306 Third, if a handler is found, the exception is caught and the handler is run.
     278Both start with the user preforming a raise on an exception.
     279Then the exception propagates up the stack.
     280If a handler is found the exception is caught and the handler is run.
    307281After that control continues at a raise-dependent location.
    308 Fourth, if a handler is not found, a default handler is run and, if it returns, then control
     282If the search fails a default handler is run and, if it returns, then control
    309283continues after the raise.
    310284
    311 %This general description covers what the two kinds have in common.
    312 The differences in the two operations include how propagation is performed, where execution continues
    313 after an exception is caught and handled, and which default handler is run.
     285This general description covers what the two kinds have in common.
     286Differences include how propagation is preformed, where exception continues
     287after an exception is caught and handled and which default handler is run.
    314288
    315289\subsection{Termination}
    316290\label{s:Termination}
    317 Termination handling is the familiar EHM and used in most programming
     291Termination handling is the familiar kind and used in most programming
    318292languages with exception handling.
    319293It is a dynamic, non-local goto. If the raised exception is matched and
     
    334308@is_termination_exception@ at the call site.
    335309Through \CFA's trait system, the trait functions are implicitly passed into the
    336 throw code for use by the EHM.
     310throw code and the EHM.
    337311A new @defaultTerminationHandler@ can be defined in any scope to
    338 change the throw's behaviour when a handler is not found (see below).
     312change the throw's behaviour (see below).
    339313
    340314The throw copies the provided exception into managed memory to ensure
     
    346320% How to say propagation starts, its first sub-step is the search.
    347321Then propagation starts with the search. \CFA uses a ``first match" rule so
    348 matching is performed with the copied exception as the search key.
    349 It starts from the raise in the throwing function and proceeds towards the base of the stack,
     322matching is preformed with the copied exception as the search continues.
     323It starts from the throwing function and proceeds towards base of the stack,
    350324from callee to caller.
    351 At each stack frame, a check is made for termination handlers defined by the
     325At each stack frame, a check is made for resumption handlers defined by the
    352326@catch@ clauses of a @try@ statement.
    353327\begin{cfa}
     
    361335\end{cfa}
    362336When viewed on its own, a try statement simply executes the statements
    363 in the \snake{GUARDED_BLOCK}, and when those are finished,
     337in \snake{GUARDED_BLOCK} and when those are finished,
    364338the try statement finishes.
    365339
     
    367341invoked functions, all the handlers in these statements are included in the
    368342search path.
    369 Hence, if a termination exception is raised, these handlers may be matched
     343Hence, if a termination exception is raised these handlers may be matched
    370344against the exception and may handle it.
    371345
    372346Exception matching checks the handler in each catch clause in the order
    373347they appear, top to bottom. If the representation of the raised exception type
    374 is the same or a descendant of @EXCEPTION_TYPE@$_i$, then @NAME@$_i$
     348is the same or a descendant of @EXCEPTION_TYPE@$_i$ then @NAME@$_i$
    375349(if provided) is
    376350bound to a pointer to the exception and the statements in @HANDLER_BLOCK@$_i$
     
    378352freed and control continues after the try statement.
    379353
    380 If no termination handler is found during the search, then the default handler
    381 (\defaultTerminationHandler) visible at the raise statement is called.
    382 Through \CFA's trait system the best match at the raise statement is used.
     354If no termination handler is found during the search then the default handler
     355(\defaultTerminationHandler) visible at the raise statement is run.
     356Through \CFA's trait system the best match at the raise statement will be used.
    383357This function is run and is passed the copied exception.
    384 If the default handler finishes, control continues after the raise statement.
     358If the default handler is run control continues after the raise statement.
    385359
    386360There is a global @defaultTerminationHandler@ that is polymorphic over all
    387361termination exception types.
     362Since it is so general a more specific handler can be
     363defined and is used for those types, effectively overriding the handler
     364for a particular exception type.
    388365The global default termination handler performs a cancellation
    389 (see \vref{s:Cancellation} for the justification) on the current stack with the copied exception.
    390 Since it is so general, a more specific handler is usually
    391 defined, possibly with a detailed message, and used for specific exception type, effectively overriding the default handler.
     366(see \vref{s:Cancellation}) on the current stack with the copied exception.
    392367
    393368\subsection{Resumption}
    394369\label{s:Resumption}
    395370
    396 Resumption exception handling is the less familar EHM, but is
     371Resumption exception handling is less common than termination but is
    397372just as old~\cite{Goodenough75} and is simpler in many ways.
    398373It is a dynamic, non-local function call. If the raised exception is
    399 matched, a closure is taken from up the stack and executed,
     374matched a closure is taken from up the stack and executed,
    400375after which the raising function continues executing.
    401376The common uses for resumption exceptions include
     
    403378function once the error is corrected, and
    404379ignorable events, such as logging where nothing needs to happen and control
    405 should always continue from the raise point.
     380should always continue from the same place.
    406381
    407382A resumption raise is started with the @throwResume@ statement:
     
    417392the exception system while handling the exception.
    418393
    419 At run-time, no exception copy is made, since
    420 resumption does not unwind the stack nor otherwise remove values from the
    421 current scope, so there is no need to manage memory to keep the exception in scope.
    422 
    423 Then propagation starts with the search. It starts from the raise in the
     394At run-time, no exception copy is made.
     395Resumption does not unwind the stack nor otherwise remove values from the
     396current scope, so there is no need to manage memory to keep things in scope.
     397
     398The EHM then begins propagation. The search starts from the raise in the
    424399resuming function and proceeds towards the base of the stack,
    425400from callee to caller.
     
    435410}
    436411\end{cfa}
    437 % PAB, you say this above.
    438 % When a try statement is executed, it simply executes the statements in the
    439 % @GUARDED_BLOCK@ and then finishes.
    440 %
    441 % However, while the guarded statements are being executed, including any
    442 % invoked functions, all the handlers in these statements are included in the
    443 % search path.
    444 % Hence, if a resumption exception is raised, these handlers may be matched
    445 % against the exception and may handle it.
    446 %
    447 % Exception matching checks the handler in each catch clause in the order
    448 % they appear, top to bottom. If the representation of the raised exception type
    449 % is the same or a descendant of @EXCEPTION_TYPE@$_i$, then @NAME@$_i$
    450 % (if provided) is bound to a pointer to the exception and the statements in
    451 % @HANDLER_BLOCK@$_i$ are executed.
    452 % If control reaches the end of the handler, execution continues after the
    453 % the raise statement that raised the handled exception.
    454 %
    455 % Like termination, if no resumption handler is found during the search,
    456 % then the default handler (\defaultResumptionHandler) visible at the raise
    457 % statement is called. It will use the best match at the raise sight according
    458 % to \CFA's overloading rules. The default handler is
    459 % passed the exception given to the raise. When the default handler finishes
    460 % execution continues after the raise statement.
    461 %
    462 % There is a global @defaultResumptionHandler{} is polymorphic over all
    463 % resumption exceptions and performs a termination throw on the exception.
    464 % The \defaultTerminationHandler{} can be overridden by providing a new
    465 % function that is a better match.
    466 
    467 The @GUARDED_BLOCK@ and its associated nested guarded statements work the same
    468 for resumption as for termination, as does exception matching at each
    469 @catchResume@. Similarly, if no resumption handler is found during the search,
    470 then the currently visible default handler (\defaultResumptionHandler) is
    471 called and control continues after the raise statement if it returns. Finally,
    472 there is also a global @defaultResumptionHandler@, which can be overridden,
    473 that is polymorphic over all resumption exceptions but performs a termination
    474 throw on the exception rather than a cancellation.
    475 
    476 Throwing the exception in @defaultResumptionHandler@ has the positive effect of
    477 walking the stack a second time for a recovery handler. Hence, a programmer has
    478 two chances for help with a problem, fixup or recovery, should either kind of
    479 handler appear on the stack. However, this dual stack walk leads to following
    480 apparent anomaly:
    481 \begin{cfa}
    482 try {
    483         throwResume E;
    484 } catch (E) {
    485         // this handler runs
    486 }
    487 \end{cfa}
    488 because the @catch@ appears to handle a @throwResume@, but a @throwResume@ only
    489 matches with @catchResume@. The anomaly results because the unmatched
    490 @catchResuem@, calls @defaultResumptionHandler@, which in turn throws @E@.
    491 
    492412% I wonder if there would be some good central place for this.
    493 Note, termination and resumption handlers may be used together
     413Note that termination handlers and resumption handlers may be used together
    494414in a single try statement, intermixing @catch@ and @catchResume@ freely.
    495415Each type of handler only interacts with exceptions from the matching
    496416kind of raise.
     417When a try statement is executed, it simply executes the statements in the
     418@GUARDED_BLOCK@ and then finishes.
     419
     420However, while the guarded statements are being executed, including any
     421invoked functions, all the handlers in these statements are included in the
     422search path.
     423Hence, if a resumption exception is raised these handlers may be matched
     424against the exception and may handle it.
     425
     426Exception matching checks the handler in each catch clause in the order
     427they appear, top to bottom. If the representation of the raised exception type
     428is the same or a descendant of @EXCEPTION_TYPE@$_i$ then @NAME@$_i$
     429(if provided) is bound to a pointer to the exception and the statements in
     430@HANDLER_BLOCK@$_i$ are executed.
     431If control reaches the end of the handler, execution continues after the
     432the raise statement that raised the handled exception.
     433
     434Like termination, if no resumption handler is found during the search,
     435the default handler (\defaultResumptionHandler) visible at the raise
     436statement is called. It will use the best match at the raise sight according
     437to \CFA's overloading rules. The default handler is
     438passed the exception given to the raise. When the default handler finishes
     439execution continues after the raise statement.
     440
     441There is a global \defaultResumptionHandler{} is polymorphic over all
     442resumption exceptions and preforms a termination throw on the exception.
     443The \defaultTerminationHandler{} can be overridden by providing a new
     444function that is a better match.
    497445
    498446\subsubsection{Resumption Marking}
    499447\label{s:ResumptionMarking}
    500448A key difference between resumption and termination is that resumption does
    501 not unwind the stack. A side effect is that, when a handler is matched
    502 and run, its try block (the guarded statements) and every try statement
     449not unwind the stack. A side effect that is that when a handler is matched
     450and run it's try block (the guarded statements) and every try statement
    503451searched before it are still on the stack. There presence can lead to
    504 the \emph{recursive resumption problem}.
     452the recursive resumption problem.
    505453
    506454The recursive resumption problem is any situation where a resumption handler
     
    516464When this code is executed, the guarded @throwResume@ starts a
    517465search and matches the handler in the @catchResume@ clause. This
    518 call is placed on the stack above the try-block. Now the second raise in the handler
    519 searches the same try block, matches, and puts another instance of the
     466call is placed on the stack above the try-block. The second raise then
     467searches the same try block and puts another instance of the
    520468same handler on the stack leading to infinite recursion.
    521469
    522 While this situation is trivial and easy to avoid, much more complex cycles can
    523 form with multiple handlers and different exception types.  The key point is
    524 that the programmer's intuition expects every raise in a handler to start
    525 searching \emph{below} the @try@ statement, making it difficult to understand
    526 and fix the problem.
    527 
    528 To prevent all of these cases, each try statement is ``marked" from the
    529 time the exception search reaches it to either when a matching handler
    530 completes or when the search reaches the base
     470While this situation is trivial and easy to avoid, much more complex cycles
     471can form with multiple handlers and different exception types.
     472
     473To prevent all of these cases, a each try statement is ``marked" from the
     474time the exception search reaches it to either when the exception is being
     475handled completes the matching handler or when the search reaches the base
    531476of the stack.
    532477While a try statement is marked, its handlers are never matched, effectively
     
    540485for instance, marking just the handlers that caught the exception,
    541486would also prevent recursive resumption.
    542 However, the rule selected mirrors what happens with termination,
    543 and hence, matches programmer intuition that a raise searches below a try.
    544 
    545 In detail, the marked try statements are the ones that would be removed from
    546 the stack for a termination exception, \ie those on the stack
     487However, these rules mirror what happens with termination.
     488
     489The try statements that are marked are the ones that would be removed from
     490the stack if this was a termination exception, that is those on the stack
    547491between the handler and the raise statement.
    548492This symmetry applies to the default handler as well, as both kinds of
     
    578522        // Only handle IO failure for f3.
    579523}
    580 // Handle a failure relating to f2 further down the stack.
     524// Can't handle a failure relating to f2 here.
    581525\end{cfa}
    582526In this example the file that experienced the IO error is used to decide
     
    609553
    610554\subsection{Comparison with Reraising}
    611 Without conditional catch, the only approach to match in more detail is to reraise
    612 the exception after it has been caught, if it could not be handled.
    613 \begin{center}
    614 \begin{tabular}{l|l}
     555A more popular way to allow handlers to match in more detail is to reraise
     556the exception after it has been caught, if it could not be handled here.
     557On the surface these two features seem interchangeable.
     558
     559If @throw;@ (no argument) starts a termination reraise,
     560which is the same as a raise but reuses the last caught exception,
     561then these two statements have the same behaviour:
    615562\begin{cfa}
    616563try {
    617         do_work_may_throw();
    618 } catch(excep_t * ex; can_handle(ex)) {
    619 
    620         handle(ex);
    621 
    622 
    623 
     564    do_work_may_throw();
     565} catch(exception_t * exc ; can_handle(exc)) {
     566    handle(exc);
    624567}
    625568\end{cfa}
    626 &
     569
    627570\begin{cfa}
    628571try {
    629         do_work_may_throw();
    630 } catch(excep_t * ex) {
    631         if (can_handle(ex)) {
    632                 handle(ex);
    633         } else {
    634                 throw;
    635         }
     572    do_work_may_throw();
     573} catch(exception_t * exc) {
     574    if (can_handle(exc)) {
     575        handle(exc);
     576    } else {
     577        throw;
     578    }
    636579}
    637580\end{cfa}
    638 \end{tabular}
    639 \end{center}
    640 Notice catch-and-reraise increases complexity by adding additional data and
    641 code to the exception process. Nevertheless, catch-and-reraise can simulate
    642 conditional catch straightforwardly, when exceptions are disjoint, \ie no
    643 inheritance.
    644 
    645 However, catch-and-reraise simulation becomes unusable for exception inheritance.
    646 \begin{flushleft}
    647 \begin{cfa}[xleftmargin=6pt]
    648 exception E1;
    649 exception E2(E1); // inheritance
    650 \end{cfa}
    651 \begin{tabular}{l|l}
    652 \begin{cfa}
    653 try {
    654         ... foo(); ... // raise E1/E2
    655         ... bar(); ... // raise E1/E2
    656 } catch( E2 e; e.rtn == foo ) {
    657         ...
    658 } catch( E1 e; e.rtn == foo ) {
    659         ...
    660 } catch( E1 e; e.rtn == bar ) {
    661         ...
    662 }
    663 
    664 \end{cfa}
    665 &
    666 \begin{cfa}
    667 try {
    668         ... foo(); ...
    669         ... bar(); ...
    670 } catch( E2 e ) {
    671         if ( e.rtn == foo ) { ...
    672         } else throw; // reraise
    673 } catch( E1 e ) {
    674         if (e.rtn == foo) { ...
    675         } else if (e.rtn == bar) { ...
    676         else throw; // reraise
    677 }
    678 \end{cfa}
    679 \end{tabular}
    680 \end{flushleft}
    681 The derived exception @E2@ must be ordered first in the catch list, otherwise
    682 the base exception @E1@ catches both exceptions. In the catch-and-reraise code
    683 (right), the @E2@ handler catches exceptions from both @foo@ and
    684 @bar@. However, the reraise misses the following catch clause. To fix this
    685 problem, an enclosing @try@ statement is need to catch @E2@ for @bar@ from the
    686 reraise, and its handler must duplicate the inner handler code for @bar@. To
    687 generalize, this fix for any amount of inheritance and complexity of try
    688 statement requires a technique called \emph{try-block
    689 splitting}~\cite{Krischer02}, which is not discussed in this thesis. It is
    690 sufficient to state that conditional catch is more expressive than
    691 catch-and-reraise in terms of complexity.
    692 
    693 \begin{comment}
    694 That is, they have the same behaviour in isolation.
     581That is, they will have the same behaviour in isolation.
    695582Two things can expose differences between these cases.
    696583
    697584One is the existence of multiple handlers on a single try statement.
    698 A reraise skips all later handlers for a try statement but a conditional
     585A reraise skips all later handlers on this try statement but a conditional
    699586catch does not.
    700 % Hence, if an earlier handler contains a reraise later handlers are
    701 % implicitly skipped, with a conditional catch they are not.
     587Hence, if an earlier handler contains a reraise later handlers are
     588implicitly skipped, with a conditional catch they are not.
    702589Still, they are equivalently powerful,
    703590both can be used two mimic the behaviour of the other,
     
    750637%   `exception_ptr current_exception() noexcept;`
    751638% https://www.python.org/dev/peps/pep-0343/
    752 \end{comment}
    753639
    754640\section{Finally Clauses}
     
    766652The @FINALLY_BLOCK@ is executed when the try statement is removed from the
    767653stack, including when the @GUARDED_BLOCK@ finishes, any termination handler
    768 finishes, or during an unwind.
     654finishes or during an unwind.
    769655The only time the block is not executed is if the program is exited before
    770656the stack is unwound.
     
    782668
    783669Not all languages with unwinding have finally clauses. Notably \Cpp does
    784 without it as destructors, and the RAII design pattern, serve a similar role.
    785 Although destructors and finally clauses can be used for the same cases,
     670without it as descructors, and the RAII design pattern, serve a similar role.
     671Although destructors and finally clauses can be used in the same cases,
    786672they have their own strengths, similar to top-level function and lambda
    787673functions with closures.
    788 Destructors take more work for their creation, but if there is clean-up code
    789 that needs to be run every time a type is used, they are much easier
     674Destructors take more work for their first use, but if there is clean-up code
     675that needs to be run every time a type is used they soon become much easier
    790676to set-up.
    791677On the other hand finally clauses capture the local context, so is easy to
    792678use when the clean-up is not dependent on the type of a variable or requires
    793679information from multiple variables.
     680% To Peter: I think these are the main points you were going for.
    794681
    795682\section{Cancellation}
     
    804691raise, this exception is not used in matching only to pass information about
    805692the cause of the cancellation.
    806 Finaly, since a cancellation only unwinds and forwards, there is no default handler.
     693(This also means matching cannot fail so there is no default handler.)
    807694
    808695After @cancel_stack@ is called the exception is copied into the EHM's memory
     
    815702After the main stack is unwound there is a program-level abort.
    816703
    817 The reasons for this semantics in a sequential program is that there is no more code to execute.
    818 This semantics also applies to concurrent programs, too, even if threads are running.
    819 That is, if any threads starts a cancellation, it implies all threads terminate.
    820 Keeping the same behaviour in sequential and concurrent programs is simple.
     704There are two reasons for these semantics.
     705The first is that it had to do this abort.
     706in a sequential program as there is nothing else to notify and the simplicity
     707of keeping the same behaviour in sequential and concurrent programs is good.
    821708Also, even in concurrent programs there may not currently be any other stacks
    822709and even if other stacks do exist, main has no way to know where they are.
     
    863750caller's context and passes it to the internal report.
    864751
    865 A coroutine only knows of two other coroutines, its starter and its last resumer.
     752A coroutine knows of two other coroutines, its starter and its last resumer.
    866753The starter has a much more distant connection, while the last resumer just
    867754(in terms of coroutine state) called resume on this coroutine, so the message
     
    871758cascade an error across any number of coroutines, cleaning up each in turn,
    872759until the error is handled or a thread stack is reached.
    873 
    874 \PAB{Part of this I do not understand. A cancellation cannot be caught. But you
    875 talk about handling a cancellation in the last sentence. Which is correct?}
Note: See TracChangeset for help on using the changeset viewer.