Why I Hate Exceptions
Exceptions, they are one of those most complex and ridiculous thing ever devised. — Jonathan Blow.
Few things you probably don't know about exceptions:
- Programming languages differ substantially in their notion of what is an exception. Your notion of Exception in Python, Java, are totally different from other language's “exception”.
- Exceptions, in most imperative languages (e.g. Java, Python, JavaScript), is a form of goto.
- In some languages, “exception” is just a syntactic form of goto, and THAT IS ALL. You write if statement to check condition, and if so and so, you call “throw”, which jumps to a “catch” in YOUR CODE. That's ALL. (for example, emacs lisp. 〔see Elisp: Exit Loop/Function, catch/throw〕)
- In some languages, such as Java, Python, exception is more than just goto, but, goto with a tree of gotos, which runs out of your control. You can simply “throw”, or simply “try”, and the language will do things in a magic realm.
- Google's new language golang, does not have exceptions, because the designers consider Exceptions harmful.
- If you don't like the typical notion of Exceptions in {C++, Java, Python}, be cheered that many well-known expert programers, do not like them neither, and never use such feature in their own code.

i've always hated exceptions. Why? it's hard to explain. (when you can't explain something in a clear and logical way, it also means you do not understand it fully)
basically, exceptions are invisible gotos. I want program languages to be modeled after formal languages, and “exceptions” doesn't fit there. 〔see Programing Language Syntax Soup〕
while randomly bitching about programing on Google Plus (https://plus.google.com/+XahLee/posts/GfdSQdMhfnq) , i had a fruitful discussion with
Nick Alcock
https://plus.google.com/115849739354666812574 and
Vance Morris
https://plus.google.com/+VanceMorris
I learned quite a lot of things. Here's the best parts.
The Semipredicate Problem
One of the thing i learned, is the term “Semipredicate problem”. The term captured the problem i had for a long time. Namely, when a function returns a value, but the function might encounter a error (For example, invalid input), how do you signal that error?
In computer programming, a semipredicate problem occurs when a subroutine intended to return a useful value can fail, but the signalling of failure uses an otherwise valid return value.[1] The problem is that the caller of the subroutine cannot tell what the result means in this case.
from Semipredicate problem ()
One simple minded solution is to have the function return a list instead. e.g. the first item is the actual result, the second contains error value. But this solution is ugly. For one thing, some of your functions will have a unnatural return structure. (languages with multi-value-returns solve this. (In golang, basically it's like returning a list, but not actual list. You get the values by assigning it to multiple variables.)) 〔see Golang: Function Multi-Value Returns〕
Example
The division operation yields a real number, but fails when the divisor is zero. If we were to write a function that performs division, we might choose to return 0 on this invalid input. However, if the dividend is 0, the result is 0 too. This means there is no number we can return to uniquely signal attempted division by zero, since all real numbers are in the range of division.
Practical implications
Early programmers dealt with potentially exceptional cases, as in the case of division, using a convention that required the calling routine to check the validity of the inputs before calling the division function. This was undesirable for two reasons. First, it greatly encumbers all code that performs division (a very common operation). Second, it violates the important principle of encapsulation in programming, whereby the handling of one issue should be contained in one place in the code. If we imagine a more complicated computation than division, the caller may not even know that invalid input is being handed to the target function; indeed, figuring out that the input is invalid may be as costly as performing the entire computation.
also, note it has this to say about exceptions:
They [exceptions] are an example of out-of-band signalling.
which captured why i hate exceptions. Exception system creates invisible exit points that runs in some magic realm.
Solutions to the Semipredicate Problem
Here is a list of solutions:
- Return a list, first element contain value, 2nd contains info about the result such as error.
- Function with multiple return values. First element contain value, 2nd contains error info, etc. You get these multiple values by assigning to multiple variables. It works like returning a list but transparent. Golang and Common Lisp are like this.
- Return a object. The object may have a property “error” with value. This is again similar to returning a list.
- Use “out parameter”. In some language, function argument can be variables, and some of the variable are used to store function's return value, and some store error/success value. (C, C++, C#)
- Use global variable for exit-status. For example, bash shell's
$?
. - Return a special value. For example, Emacs Lisp
nil
. Other lang'snull
,-1
, or return the whole symbolic expression unchanged (e.g. Wolfram Language). - Return a special type. For example, Haskell.
〔see Golang: Function Multi-Value Returns〕
Your Exception is Not My Exception
According to a 2006 comparative paper by Joseph R. Kiniry, programming languages differ substantially in their notion of what is an exception. According to Kiniry, the contemporary languages can be roughly divided in two groups:[7]
- those languages in which exceptions “are designed to be used as flow control structures”; according to this paper, Ada, C++, Java, Modula-3, ML, OCaml, Python, and Ruby fall in this category
- those languages in which exceptions “are designed to represent and handle abnormal, unpredictable, erroneous situations”; according to the paper these include: C#, Common Lisp, Eiffel, and Modula-2
How Do People Use Exceptions?
How do people use exceptions, depends on lots things. The language, the documentation, the marketing, the style guide, the community.
Kiniry also notes that “Language design only partially influences the use of exceptions, and consequently, the manner in which one handles partial and total failures during system execution. The other major influence is examples of use, typically in core libraries and code examples in technical books, magazine articles, and online discussion forums, and in an organization's code standards.”[7]
Contemporary applications face many design challenges when considering exception handling strategies. Particularly in modern enterprise level applications, exceptions must often cross process boundaries and machine boundaries. Part of designing a solid exception handling strategy is recognizing when a process has failed to the point where it cannot be economically handled by the software portion of the process.[8]
Exceptions in the Wild, Badly Used
Exception handling is often not handled correctly in software, especially when there are multiple sources of exceptions; data flow analysis of 5 million lines of Java code found over 1300 exception handling defects.[9]
Exception History
- Software exception handling developed in Lisp in the 1960s and 1970s.
- This originated in LISP 1.5 (1962), where exceptions were caught by the ERRSET keyword, which returned NIL in case of an error, instead of terminating the program or entering the debugger.[10]
- Error raising was introduced in MacLisp in the late 1960s via the ERR keyword.[10] This was rapidly used not only for error raising, but for non-local control flow, and thus was augmented by two new keywords, CATCH and THROW (MacLisp June 1972), reserving ERRSET and ERR for error handling.
- The cleanup behavior now generally called "finally" was introduced in NIL (New Implementation of LISP) in the mid- to late-1970s as UNWIND-PROTECT.[11] This was then adopted by Common Lisp.
- Contemporary with this was dynamic-wind in Scheme, which handled exceptions in closures.
- The first papers on structured exception handling were Goodenough (1975a) and Goodenough (1975b).[12] Exception handling was subsequently widely adopted by many programming languages from the 1980s onward.
Originally software exception handling included both resumable exceptions (resumption semantics), like most hardware exceptions, and non-resumable exceptions (termination semantics). However, resumption semantics proved ineffective in practice[citation needed] in the 1970s and 1980s, and are no longer in common use.
Note: according to the Wikipedia article, one of the early language to use exception is MacLisp. Now, Emacs Lisp is descended from MacLisp.
In elisp, the catch
and throw
is merely a form of goto.
And there's also function error
for creating error, and
function condition-case
for checking error,
unwind-protect
that is like “finally” for cleaning up.
There's no hierachy of exception system.
Nonlocal Exits (ELISP Manual)
Problems of Exceptions
A contrasting view on the safety of exception handling was given by C.A.R Hoare in 1980, described the Ada programming language as having “…a plethora of features and notational conventions, many of them unnecessary and some of them, like exception handling, even dangerous. […] Do not allow this language in its present state to be used in applications where reliability is critical[…]. The next rocket to go astray as a result of a programming language error may not be an exploratory space rocket on a harmless trip to Venus: It may be a nuclear warhead exploding over one of our own cities.” [14]
Citing multiple prior studies by others (1999 to 2004) and their own results, Weimer and Necula wrote that a significant problem with exceptions is that they “create hidden control-flow paths that are difficult for programmers to reason about”.[9]:8:27
some other's opinions.
- Exceptions are gotos, but worse, invisible gotos.
- Exceptions create many invisible exit points.

Exceptions Considered Harmful or: throw is just goto in drag By Jules. At http://blog.deprogramandis.co.uk/2012/06/02/exceptions-considered-harmful-or-throw-is-just-goto-in-drag/ Exceptions considered harmful By Dennis Gurzhii. At http://blogs.msdn.com/b/dennisg/archive/2012/04/28/exceptions-considered-harmful.aspxException Handling Considered Harmful By Jason Robert Carey Patterson. At http://www.lighterra.com/papers/exceptionsharmful/
see also, this video, starting at 38:40, about exceptions being the worst invention in programing language.

- https://youtu.be/TH9VCN6UkyQ
- Ideas about a new programming language for games.
- by Jonathan Blow.
- Published on Sep 19, 2014
Exception in Haskell
by Yuri Khan,
(Yuri Khan https://yurikhan.dreamwidth.org/)
OK, let's consider Haskell. The canonical textbook explanation of error handling in Haskell goes like this:
Functions that may not be defined for all possible inputs are called “partial functions”.
The simplest way to represent a partial function is the Maybe resultType
monad.
A successful return with value x
is represented as Just x
, while an error is represented as Nothing
.
Monadic functions may be chained; if any function in the chain returns Nothing
, the whole chain returns Nothing
.
(This provides the error autopropagation issue.)
myDivide :: Fractional a => a -> a -> Maybe a myDivide _ 0 = Nothing myDivide x y = x / y
But returning just one error return value is insufficient for real world programming; at a minimum, we'd like to return a human-readable errror description.
Instead of Maybe resultType
, we can return Either String resultType
, where a Right x
value represents a successful return, and a Left "something went wrong"
represents an error and provides specific error details. Either a
is also a monad and so a function f :: a -> Either e b
can be chained with g :: b -> Either e c
, to yield a composite function :: a -> Either e c
.
A chain of functions returns the earliest error, or if none
occur, the successful result of the last function in chain.
But human-readable error messages are not very useful within programs; you could say we don't have the exception type tagging property.
To this end, we can use Either
with a custom error type instead of String
, for example, Either (ErrorCode, String) resultType
.
This way, error objects are machine-readable; we can switch on the error code and decide which errors to handle and which to propagate.
(For example, a function that uses a configuration file might query the configuration file for an option, and if this fails because the option is unconfigured, use a default value; but if it fails because the option value is syntactically incorrect, fail.)
But in order for this approach to work in large, the ErrorCode has to be the same throughout the program, which is hard to achieve if you use libraries.
This is because the Either (ErrorCode, String) resultType mechanism lacks extensibility.
For that reason, several exception support modules (Control.Exception
, Control.Monad.Exception
) are devised.
I am not prepared to give a good analysis on those right now, but I see that they achieve extensibility by defining a typeclass that can be defined for any client-defined error type.
Note: Haskell's exception is completely different than the common notion of Exception in Java, Python. Haskell's exception's is not invisible goto, nor is it multiple exit point. Rather, it's like returning a multiple value, but without needing to check at each call, as the type system makes it a smooth flow.
Programing Language Design
- Ontology of Programing Languages
- A Class of Programing Languages: Math Languages
- Why I Hate Exceptions
- Iterator, Enumerator, Abstraction Went Wrong
- Should Array Index Start at 0 or 1?
- Where does the “main” function in programing languages came from?
- Syntactic Semantic Difference of Map
- Should Map f Specify Order?
- Abuse of Logic Operators (Short-Circuit) as Control Flow
- Programing Language Idiocy: Bit Operators
- Hack of Bitmask as Boolean Parameters
- Function Dependency
- The Complexity of Java Access Specifiers