
Bruce Eckel is Wrong - vijaydev
http://cafe.elharo.com/programming/bruce-eckel-is-wrong/
======
lyudmil
I know Mr. Harold is much more experienced than me. It's pretty obvious he's
more of an authority on most programming subjects. With that caveat I give my
reasons why I despise checked exceptions in Java.

I've never seen code that got cleaner because of the use of checked
exceptions. If you have a fairly complex piece of functionality that you've
refactored mercilessly, it is quite possible to end up with a deep object
hierarchy. If the checked exception is thrown at the bottom, that pollutes
every interface on the way up the call chain to the method where the exception
is handled. Also, whenever you are ready to catch the exception, you have to
have a try/catch block and that aesthetically looks like an if-else statement,
which means it is really easy to write it in an ugly way (merely having 3
lines of code for each the try and catch part is enough). All of this
inevitably slows me down as I have to come up with a way to deal with those
problems. It also frequently tempts me to just eat the checked exception
rather than handle it.

I also think throwing a checked exception assumes too much about how I want to
use that particular class/function. Suppose I'm using some sort of parsing
tool to test complicated output (say, HTML). I'm only using this in tests. I
do not want to have to handle exceptions. Even if it was in production code I
may not actually care about addressing anything but the happy path.

I cannot effectively argue I'm not a newbie, writing buggy, shaky software.
But I can't help but feel that the concerns of most programmers are more
aligned with mine.

------
fhars
His argument that a library that accepts an interface without declaring all
possible exceptions a method of that interface might throw is badly designed
is misguided. This assumes that the writer of the library can know all
possible custom exceptions that code written by the user might throw, which is
impossible. But it is perfectly valid if the code that calls the library
passes in an instance implementing the interface that might throw a
CantFrobnicateException that the library doesn't know anything about if the
calling code knows what to do if the library call fails with that exception.

The real design error here are still checked exceptions. What you really want
are dynamic exceptions with an optional whole program analyzer that detects
possible code paths that could lead to uncaught exceptions.

------
barrkel
Elliotte Rusty Harold is wrong.

Checked exceptions are problematic because they version poorly, they
implicitly presume the wrong model of exception _handling_ , and more
importantly, they prematurely decide the application's desired policy for
error handling by encoding the "checkedness" in the type itself, where it is
not available for configuration by the programmer.

The poor versioning is obvious. The OP says _"The superclass/interface was not
designed properly for extension. Specifically it did not take into account the
exceptions overriders/implementers might reasonably want to throw"_ \- and the
only problem with that is the well-known difficulty in predicting the future.

But actually, it's more subtle: exceptions are usually a desired encapsulation
violation. When programming to an abstract interface, you don't want to know
the details of how it's implemented, but all the ways it can fail are a
_function_ of how it's implemented. You can't reasonably require the design of
the most abstract levels of the system to predict every possible low-level
implementation failure and state them out long-hand; the only reasonable
implementation would be "throws Exception", which defeats the whole point of
checked exceptions.

By presuming the wrong model of handling, I'm referring to the burden of
creating a tunnel through the type system for your exception type between the
point of the throw and the point of the catch. This burden is set up to
optimize for catching sooner rather than later. But the thing is, usually you
never want to catch; usually, the only exception catching you want done is at
the highest levels of the system, in an event loop or request dispatcher. If
you were expecting an exception you'd want to catch, the situation isn't
exceptional; instead, you shouldn't be using an API that throws. .NET's
pattern of e.g. Int32.Parse() vs Int32.TryParse() exemplifies this.

The OP tries to argue against this with the distinction between runtime errors
and exceptions: _"checked exceptions do not require the programmer to provide
handlers in situations where no meaningful action can be taken. When no
meaningful action can be taken Java programs throw Errors"_. And this brings
me to my third point. The determination for whether meaningful action can be
taken _varies from program to program_ , and is encoded in the very exception
handlers themselves - i.e. it's the programmer who makes that choice, not the
people who defined the relevant exception types.

His examples of error - _out of memory error, stack overflow, class not found,
etc._ \- actually make more sense as reasons to completely terminate the
application, rather than make any attempt to catch. They're not really errors
so much as panics.

~~~
d0mine
If you application is a server then _out of memory error_ during a request
means that the request failed but not that you should shut down the server.

 _class not found_ means that some functionality is unavailable but you could
provide a workaround that might have some disadvantages compared to the absent
version but would work. For example, in Python ( _ImportError_ plays role of
_class not found_ here)

    
    
      try:
          import cElementTree as ElementTree  # fast C extension
      except ImportError:
          from elementtree import ElementTree # ~30 time slower
    

Don't panic ;)

~~~
sbov
I'd rather have my application fail clearly and obviously than have it start
to mysteriously run 30 times slower.

At least in Java on the server side, most checked exceptions I run across fall
under this umbrella. If they happen, something is really really wrong.

~~~
d0mine
If the code is in a library it is not your call to decide what is satisfactory
performance and what requirements are. A user of your library could decide
that running this code inside JVM (via Jython) is more important than using C
extensions for speed.

Real world example, an excellent tool -- Universal Feed Parser
<http://www.feedparser.org/>

    
    
      # If a real XML parser is available, feedparser will attempt to use it.  feedparser has
      # been tested with the built-in SAX parser, PyXML, and libxml2.  On platforms where the
      # Python distribution does not come with an XML parser (such as Mac OS X 10.2 and some
      # versions of FreeBSD), feedparser will quietly fall back on regex-based parsing.
      try:
          import xml.sax
          xml.sax.make_parser(PREFERRED_XML_PARSERS) # test for valid parsers
          from xml.sax.saxutils import escape as _xmlescape
          _XML_AVAILABLE = 1
      except:
          _XML_AVAILABLE = 0
          def _xmlescape(data,entities={}):
              data = data.replace('&', '&amp;')
              data = data.replace('>', '&gt;')
              data = data.replace('<', '&lt;')
              for char, entity in entities:
                  data = data.replace(char, entity)
              return data

