Ignore:
Timestamp:
Sep 27, 2021, 2:09:55 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
cc287800
Parents:
4e28d2e9 (diff), 056cbdb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

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

    r4e28d2e9 r949339b  
    2525All types of exception handling link a raise with a handler.
    2626Both operations are usually language primitives, although raises can be
    27 treated as a primitive function that takes an exception argument.
    28 Handlers are more complex as they are added to and removed from the stack
    29 during execution, must specify what they can handle and give the code to
     27treated as a function that takes an exception argument.
     28Handlers are more complex, as they are added to and removed from the stack
     29during execution, must specify what they can handle and must give the code to
    3030handle the exception.
    3131
     
    3939it returns control to that function.
    4040\begin{center}
    41 \input{termination}
     41%\input{termination}
     42%
     43%\medskip
     44\input{termhandle.pstex_t}
     45% I hate these diagrams, but I can't access xfig to fix them and they are
     46% better than the alternative.
    4247\end{center}
    4348
     
    4651The handler is run on top of the existing stack, often as a new function or
    4752closure capturing the context in which the handler was defined.
    48 After the handler has finished running it returns control to the function
     53After the handler has finished running, it returns control to the function
    4954that preformed the raise, usually starting after the raise.
    5055\begin{center}
    51 \input{resumption}
     56%\input{resumption}
     57%
     58%\medskip
     59\input{resumhandle.pstex_t}
     60% The other one.
    5261\end{center}
    5362
    5463Although a powerful feature, exception handling tends to be complex to set up
    55 and expensive to use
     64and expensive to use,
    5665so it is often limited to unusual or ``exceptional" cases.
    57 The classic example is error handling, exceptions can be used to
     66The classic example is error handling; exceptions can be used to
    5867remove error handling logic from the main execution path, and pay
    5968most of the cost only when the error actually occurs.
     
    6372The \CFA EHM implements all of the common exception features (or an
    6473equivalent) found in most other EHMs and adds some features of its own.
    65 The design of all the features had to be adapted to \CFA's feature set as
     74The design of all the features had to be adapted to \CFA's feature set, as
    6675some of the underlying tools used to implement and express exception handling
    6776in other languages are absent in \CFA.
    68 Still the resulting syntax resembles that of other languages:
     77Still, the resulting syntax resembles that of other languages:
    6978\begin{cfa}
    7079try {
     
    8897covering both changes to the compiler and the run-time.
    8998In addition, a suite of test cases and performance benchmarks were created
    90 along side the implementation.
     99alongside the implementation.
    91100The implementation techniques are generally applicable in other programming
    92101languages and much of the design is as well.
     
    100109\item Implementing stack unwinding and the \CFA EHM, including updating
    101110the \CFA compiler and the run-time environment.
    102 \item Designed and implemented a prototype virtual system.
     111\item Designing and implementing a prototype virtual system.
    103112% I think the virtual system and per-call site default handlers are the only
    104113% "new" features, everything else is a matter of implementation.
    105114\item Creating tests to check the behaviour of the EHM.
    106 \item Creating benchmarks to check the performances of the EHM,
     115\item Creating benchmarks to check the performance of the EHM,
    107116as compared to other languages.
    108117\end{enumerate}
     
    110119The rest of this thesis is organized as follows.
    111120The current state of exceptions is covered in \autoref{s:background}.
    112 The existing state of \CFA is also covered in \autoref{c:existing}.
     121The existing state of \CFA is covered in \autoref{c:existing}.
    113122New EHM features are introduced in \autoref{c:features},
    114123covering their usage and design.
     
    129138message as a payload\cite{Ada12}.
    130139
    131 The modern flag-ship for termination exceptions is \Cpp,
     140The modern flagship for termination exceptions -- if one exists -- is \Cpp,
    132141which added them in its first major wave of non-object-orientated features
    133142in 1990.\cite{CppHistory}
     
    137146inheriting from
    138147\code{C++}{std::exception}.
    139 Although there is a special catch-all syntax (@catch(...)@) there are no
     148Although there is a special catch-all syntax (@catch(...)@), there are no
    140149operations that can be performed on the caught value, not even type inspection.
    141 Instead the base exception-type \code{C++}{std::exception} defines common
     150Instead, the base exception-type \code{C++}{std::exception} defines common
    142151functionality (such as
    143152the ability to describe the reason the exception was raised) and all
     
    148157
    149158Java was the next popular language to use exceptions.\cite{Java8}
    150 Its exception system largely reflects that of \Cpp, except that requires
     159Its exception system largely reflects that of \Cpp, except that it requires
    151160you throw a child type of \code{Java}{java.lang.Throwable}
    152161and it uses checked exceptions.
    153162Checked exceptions are part of a function's interface,
    154163the exception signature of the function.
    155 Every function that could be raised from a function, either directly or
     164Every exception that could be raised from a function, either directly or
    156165because it is not handled from a called function, is given.
    157166Using this information, it is possible to statically verify if any given
    158 exception is handled and guarantee that no exception will go unhandled.
     167exception is handled, and guarantee that no exception will go unhandled.
    159168Making exception information explicit improves clarity and safety,
    160169but can slow down or restrict programming.
     
    169178recovery or repair. In theory that could be good enough to properly handle
    170179the exception, but more often is used to ignore an exception that the       
    171 programmer does not feel is worth the effort of handling it, for instance if
     180programmer does not feel is worth the effort of handling, for instance if
    172181they do not believe it will ever be raised.
    173 If they are incorrect the exception will be silenced, while in a similar
     182If they are incorrect, the exception will be silenced, while in a similar
    174183situation with unchecked exceptions the exception would at least activate   
    175 the language's unhandled exception code (usually program abort with an 
     184the language's unhandled exception code (usually, a program abort with an
    176185error message).
    177186
    178187%\subsection
    179188Resumption exceptions are less popular,
    180 although resumption is as old as termination; hence, few
     189although resumption is as old as termination; that is, few
    181190programming languages have implemented them.
    182191% http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/parc/techReports/
     
    186195included in the \Cpp standard.
    187196% https://en.wikipedia.org/wiki/Exception_handling
    188 Since then resumptions have been ignored in main-stream programming languages.
     197Since then, resumptions have been ignored in mainstream programming languages.
    189198However, resumption is being revisited in the context of decades of other
    190199developments in programming languages.
    191200While rejecting resumption may have been the right decision in the past,
    192201the situation has changed since then.
    193 Some developments, such as the function programming equivalent to resumptions,
     202Some developments, such as the functional programming equivalent to resumptions,
    194203algebraic effects\cite{Zhang19}, are enjoying success.
    195 A complete reexamination of resumptions is beyond this thesis,
    196 but there reemergence is enough to try them in \CFA.
     204A complete reexamination of resumption is beyond this thesis,
     205but their reemergence is enough reason to try them in \CFA.
    197206% Especially considering how much easier they are to implement than
    198207% termination exceptions and how much Peter likes them.
     
    208217
    209218%\subsection
    210 More recently exceptions seem to be vanishing from newer programming
     219More recently, exceptions seem to be vanishing from newer programming
    211220languages, replaced by ``panic".
    212221In Rust, a panic is just a program level abort that may be implemented by
    213222unwinding the stack like in termination exception
    214223handling.\cite{RustPanicMacro}\cite{RustPanicModule}
    215 Go's panic through is very similar to a termination, except it only supports
     224Go's panic though is very similar to a termination, except it only supports
    216225a catch-all by calling \code{Go}{recover()}, simplifying the interface at
    217226the cost of flexibility.\cite{Go:2021}
    218227
    219228%\subsection
    220 While exception handling's most common use cases are in error handling,
     229As exception handling's most common use cases are in error handling,
    221230here are some other ways to handle errors with comparisons with exceptions.
    222231\begin{itemize}
     
    233242is discarded to avoid this problem.
    234243Checking error codes also bloats the main execution path,
    235 especially if the error is not handled immediately hand has to be passed
     244especially if the error is not handled immediately and has to be passed
    236245through multiple functions before it is addressed.
     246
     247Here is an example of the pattern in Bash, where commands can only  ``return"
     248numbers and most output is done through streams of text.
     249\begin{lstlisting}[language=bash,escapechar={}]
     250# Immediately after running a command:
     251case $? in
     2520)
     253        # Success
     254        ;;
     2551)
     256        # Error Code 1
     257        ;;
     2582|3)
     259        # Error Code 2 or Error Code 3
     260        ;;
     261# Add more cases as needed.
     262asac
     263\end{lstlisting}
    237264
    238265\item\emph{Special Return with Global Store}:
    239266Similar to the error codes pattern but the function itself only returns
    240 that there was an error
    241 and store the reason for the error in a fixed global location.
    242 For example many routines in the C standard library will only return some
     267that there was an error,
     268and stores the reason for the error in a fixed global location.
     269For example, many routines in the C standard library will only return some
    243270error value (such as -1 or a null pointer) and the error code is written into
    244271the standard variable @errno@.
    245272
    246273This approach avoids the multiple results issue encountered with straight
    247 error codes but otherwise has the same disadvantages and more.
     274error codes as only a single error value has to be returned,
     275but otherwise has the same disadvantages and more.
    248276Every function that reads or writes to the global store must agree on all
    249277possible errors and managing it becomes more complex with concurrency.
     278
     279This example shows some of what has to be done to robustly handle a C
     280standard library function that reports errors this way.
     281\begin{lstlisting}[language=C]
     282// Now a library function can set the error.
     283int handle = open(path_name, flags);
     284if (-1 == handle) {
     285        switch (errno) {
     286    case ENAMETOOLONG:
     287                // path_name is a bad argument.
     288                break;
     289        case ENFILE:
     290                // A system resource has been exausted.
     291                break;
     292        // And many more...
     293    }
     294}
     295\end{lstlisting}
     296% cite open man page?
    250297
    251298\item\emph{Return Union}:
     
    253300Success is one tag and the errors are another.
    254301It is also possible to make each possible error its own tag and carry its own
    255 additional information, but the two branch format is easy to make generic
     302additional information, but the two-branch format is easy to make generic
    256303so that one type can be used everywhere in error handling code.
    257304
    258305This pattern is very popular in any functional or semi-functional language
    259306with primitive support for tagged unions (or algebraic data types).
     307Return unions can also be expressed as monads (evaluation in a context)
     308and often are in languages with special syntax for monadic evaluation,
     309such as Haskell's \code{haskell}{do} blocks.
     310
     311The main advantage is that an arbitrary object can be used to represent an
     312error, so it can include a lot more information than a simple error code.
     313The disadvantages include that the it does have to be checked along the main
     314execution, and if there aren't primitive tagged unions proper, usage can be
     315hard to enforce.
    260316% We need listing Rust/rust to format code snippets from it.
    261317% Rust's \code{rust}{Result<T, E>}
    262 The main advantage is that an arbitrary object can be used to represent an
    263 error so it can include a lot more information than a simple error code.
    264 The disadvantages include that the it does have to be checked along the main
    265 execution and if there aren't primitive tagged unions proper usage can be
    266 hard to enforce.
     318
     319This is a simple example of examining the result of a failing function in
     320Haskell, using its \code{haskell}{Either} type.
     321Examining \code{haskell}{error} further would likely involve more matching,
     322but the type of \code{haskell}{error} is user defined so there are no
     323general cases.
     324\begin{lstlisting}[language=haskell]
     325case failingFunction argA argB of
     326    Right value -> -- Use the successful computed value.
     327    Left error -> -- Handle the produced error.
     328\end{lstlisting}
     329
     330Return unions as monads will result in the same code, but can hide most
     331of the work to propagate errors in simple cases. The code to actually handle
     332the errors, or to interact with other monads (a common case in these
     333languages) still has to be written by hand.
     334
     335If \code{haskell}{failingFunction} is implemented with two helpers that
     336use the same error type, then it can be implemented with a \code{haskell}{do}
     337block.
     338\begin{lstlisting}[language=haskell,literate={}]
     339failingFunction x y = do
     340        z <- helperOne x
     341        helperTwo y z
     342\end{lstlisting}
    267343
    268344\item\emph{Handler Functions}:
     
    274350variable).
    275351C++ uses this approach as its fallback system if exception handling fails,
    276 such as \snake{std::terminate_handler} and, for a time,
    277 \snake{std::unexpected_handler}.
     352such as \snake{std::terminate} and, for a time,
     353\snake{std::unexpected}.\footnote{\snake{std::unexpected} was part of the
     354Dynamic Exception Specification, which has been removed from the standard
     355as of C++20.\cite{CppExceptSpec}}
    278356
    279357Handler functions work a lot like resumption exceptions,
     
    283361function calls, but cheaper (constant time) to call,
    284362they are more suited to more frequent (less exceptional) situations.
     363Although, in \Cpp and other languages that do not have checked exceptions,
     364they can actually be enforced by the type system be more reliable.
     365
     366This is a more local example in \Cpp, using a function to provide
     367a default value for a mapping.
     368\begin{lstlisting}[language=C++]
     369ValueT Map::key_or_default(KeyT key, ValueT(*make_default)(KeyT)) {
     370        ValueT * value = find_value(key);
     371        if (nullptr != value) {
     372                return *value;
     373        } else {
     374                return make_default(key);
     375        }
     376}
     377\end{lstlisting}
    285378\end{itemize}
    286379
     
    288381Because of their cost, exceptions are rarely used for hot paths of execution.
    289382Hence, there is an element of self-fulfilling prophecy as implementation
    290 techniques have been focused on making them cheap to set-up,
     383techniques have been focused on making them cheap to set up,
    291384happily making them expensive to use in exchange.
    292385This difference is less important in higher-level scripting languages,
    293 where using exception for other tasks is more common.
     386where using exceptions for other tasks is more common.
    294387An iconic example is Python's
    295 \code{Python}{StopIteration}\cite{PythonExceptions} exception that
     388\code{Python}{StopIteration}\cite{PythonExceptions} exception, that
    296389is thrown by an iterator to indicate that it is exhausted.
    297 When paired with Python's iterator-based for-loop this will be thrown every
     390When paired with Python's iterator-based for-loop, this will be thrown every
    298391time the end of the loop is reached.\cite{PythonForLoop}
Note: See TracChangeset for help on using the changeset viewer.