notes-computer-programming-programmingLanguagesBook-programmingLanguagesChError

Table of Contents for Programming Languages: a survey

Chapter : error handling

exceptions

checked or not

resumable or not

catch-all exception handlers (and how to represent arbitrary exceptions in statically typed languages; C++ allows any type to be thrown but perhaps the language should force them all to derive from Exception?)

'escape continuations'

golang panics: http://golang.org/doc/effective_go.html#errors . Note that golang's 'recover' also doubles as an 'was this defer involked as a result of a panic within this function?' boolean function that is called within 'defer's. 'recover' returns nil (e.g. i am not panicing as a result of a panic WITHIN THIS FUNCTION) when it is called within other defer blocks placed within other functions that are called from the initial defer.

note the similarities to try..catch blocks. panics and recovers are similar to exceptions with try..catch in that the panic can pass information on what type of problem it is, and recovers can receive that information and 'catch' the panic, and uncaught panics 'bubble up' and can be 'caught' further up.

finally finally vs. golang defer (defer allows the final code to be placed anywhere in the block corresponding to the 'try' block, so for example if you use it to close a file, you can put it right after the file open command; note that defer executes immediately before the function enclosing it returns, not at the end of the enclosing block; note also that in go, since there is no 'try/catch', a 'recover' from a 'panic' must be inside a 'deer' block, since 'defer' is the only things evaluated as the stack is unwound (http://golang.org/doc/effective_go.html#errors) ) finally vs. python with vs. C# using

(a) benefit to exceptions vs error codes: with error codes, you can silently neglect to check the error code; with exceptions, ignoring the exception is visible

(an) objection to exceptions: non-local control flow

objection to exceptions: http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

todo look again at section "what's wrong with c++ exceptions?" in [1]

todo summarize [2] (upfront boilerplate, versioning, scalability)

exception safety

" A piece of code is said to be exception-safe, if run-time failures within the code will not produce ill effects, such as memory leaks, garbled stored data, or invalid output. Exception-safe code must satisfy invariants placed on the code even if exceptions occur. There are several levels of exception safety:

    Failure transparency, also known as the no throw guarantee: Operations are guaranteed to succeed and satisfy all requirements even in presence of exceptional situations. If an exception occurs, it will not throw the exception further up. (Best level of exception safety.)
    Commit or rollback semantics, also known as strong exception safety or no-change guarantee: Operations can fail, but failed operations are guaranteed to have no side effects so all data retain original values.
    Basic exception safety: Partial execution of failed operations can cause side effects, but invariants on the state are preserved. Any stored data will contain valid values even if data has different values now from before the exception.
    Minimal exception safety also known as no-leak guarantee: Partial execution of failed operations may store invalid data but will not cause a crash, and no resources get leaked.
    No exception safety: No guarantees are made. (Worst level of exception safety)" -- https://en.wikibooks.org/wiki/C%2B%2B_Programming/Exception_Handling

maybe

todo reread 6 ways to handle errors in haskell

also called Option in e.g. Scala, Java 8, Apple Swift

nullable types

nan vs none vs missing/masked

http://lambda-the-ultimate.org/node/3186 "Null References: The Billion Dollar Mistake"

issue: handling inconsistent state after an error

Imagine that you have 3 data representations that must be kept in sync. You need to modify them. What if, when you try to modify the second one, an error occurs, leaving you unable to modify it at this time?

You have already modified the first one. Since modifying the second one is not possible, you must attempt to undo the change made to the first one.

Similarly, if you find that you are unable to modify the third one, you must undo the changes to both the first and the second one.

Using either error codes or exceptions, this leads to adding a lot of logic to your code. If you have N data representations to keep in sync, you end up writing n items of code to modify them, plus (1 + 2 + ... + n-1) = 0.5*n^2 items of code to potentially undo the previous steps in case of an error!

Two ways to simplify the situation are transactions and ScopeGuard?.

transactions

ScopeGuard

Something that will be called when the current scope is exited, UNLESS it is dismissed before that point.

See http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758

like golang defer, but dismissable

D has this facility via scope(failure):

http://dlang.org/statement.html#ScopeGuardStatement

http://dlang.org/exception-safe.html