Changeset 9411cf0
- Timestamp:
- Sep 24, 2021, 12:09:38 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- f93c50a
- Parents:
- 814f87d
- Location:
- doc/theses/andrew_beach_MMath
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/andrew_beach_MMath/features.tex
r814f87d r9411cf0 495 495 496 496 For example, consider an error reading a configuration file. 497 This is most likely a problem with the configuration file @config_error@,498 but the function could have been passed the wrong file name @arg_error@.497 This is most likely a problem with the configuration file (@config_error@), 498 but the function could have been passed the wrong file name (@arg_error@). 499 499 In this case the function could raise one exception and then, if it is 500 500 unhandled, raise the other. … … 574 574 For instance, a resumption used to send messages to the logger may not 575 575 need to be handled at all. Putting the following default handler 576 at the global scope can make handling th eexception optional by default.576 at the global scope can make handling that exception optional by default. 577 577 \begin{cfa} 578 578 void defaultResumptionHandler(log_message &) { -
doc/theses/andrew_beach_MMath/intro.tex
r814f87d r9411cf0 39 39 it returns control to that function. 40 40 \begin{center} 41 \input{termination}42 43 \medskip41 %\input{termination} 42 % 43 %\medskip 44 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. 45 47 \end{center} 46 \todo*{Can I make the new diagrams fit the old style?}47 48 48 49 Resumption exception handling searches the stack for a handler and then calls … … 53 54 that preformed the raise, usually starting after the raise. 54 55 \begin{center} 55 \input{resumption}56 57 \medskip56 %\input{resumption} 57 % 58 %\medskip 58 59 \input{resumhandle.pstex_t} 60 % The other one. 59 61 \end{center} 60 62 … … 243 245 through multiple functions before it is addressed. 244 246 247 Here is an example of the pattern in Bash, where commands can only ``return" 248 numbers and most output is done through streams of text. 249 \begin{lstlisting}[language=bash,escapechar={}] 250 # Immediately after running a command: 251 case $? in 252 0) 253 # Success 254 ;; 255 1) 256 # Error Code 1 257 ;; 258 2|3) 259 # Error Code 2 or Error Code 3 260 ;; 261 # Add more cases as needed. 262 asac 263 \end{lstlisting} 264 245 265 \item\emph{Special Return with Global Store}: 246 266 Similar to the error codes pattern but the function itself only returns … … 252 272 253 273 This approach avoids the multiple results issue encountered with straight 254 error codes but otherwise has the same disadvantages and more. 274 error codes as only a single error value has to be returned, 275 but otherwise has the same disadvantages and more. 255 276 Every function that reads or writes to the global store must agree on all 256 277 possible errors and managing it becomes more complex with concurrency. 278 279 This example shows some of what has to be done to robustly handle a C 280 standard library function that reports errors this way. 281 \begin{lstlisting}[language=C] 282 // Make sure to clear the store. 283 errno = 0; 284 // Now a library function can set the error. 285 int handle = open(path_name, flags); 286 if (-1 == handle) { 287 switch (errno) { 288 case ENAMETOOLONG: 289 // path_name is a bad argument. 290 break; 291 case ENFILE: 292 // A system resource has been exausted. 293 break; 294 // And many more... 295 } 296 } 297 \end{lstlisting} 298 % cite open man page? 257 299 258 300 \item\emph{Return Union}: … … 277 319 % Rust's \code{rust}{Result<T, E>} 278 320 321 This is a simple example of examining the result of a failing function in 322 Haskell, using its \code{haskell}{Either} type. 323 Examining \code{haskell}{error} further would likely involve more matching, 324 but the type of \code{haskell}{error} is user defined so there are no 325 general cases. 326 \begin{lstlisting}[language=haskell] 327 case failingFunction argA argB of 328 Right value -> -- Use the successful computed value. 329 Left error -> -- Handle the produced error. 330 \end{lstlisting} 331 279 332 Return unions as monads will result in the same code, but can hide most 280 333 of the work to propagate errors in simple cases. The code to actually handle 281 334 the errors, or to interact with other monads (a common case in these 282 335 languages) still has to be written by hand. 336 337 If \code{haskell}{failingFunction} is implemented with two helpers that 338 use the same error type, then it can be implemented with a \code{haskell}{do} 339 block. 340 \begin{lstlisting}[language=haskell] 341 failingFunction x y = do 342 z <- helperOne x 343 helperTwo y z 344 \end{lstlisting} 283 345 284 346 \item\emph{Handler Functions}: … … 301 363 function calls, but cheaper (constant time) to call, 302 364 they are more suited to more frequent (less exceptional) situations. 365 Although, in \Cpp and other languages that do not have checked exceptions, 366 they can actually be enforced by the type system be more reliable. 367 368 This is a more local example in \Cpp, using a function to provide 369 a default value for a mapping. 370 \begin{lstlisting}[language=C++] 371 ValueT Map::key_or_default(KeyT key, ValueT(*make_default)(KeyT)) { 372 ValueT * value = find_value(key); 373 if (nullptr != value) { 374 return *value; 375 } else { 376 return make_default(key); 377 } 378 } 379 \end{lstlisting} 303 380 \end{itemize} 304 381
Note: See TracChangeset
for help on using the changeset viewer.