Checked vs unchecked exceptions

Marco Leise via Digitalmars-d digitalmars-d at puremagic.com
Fri Jul 7 11:48:31 PDT 2017


Am Thu, 06 Jul 2017 13:16:23 +0000
schrieb Moritz Maxeiner <moritz at ucworks.org>:

> On Thursday, 6 July 2017 at 11:01:26 UTC, Marco Leise wrote:
> > Am Thu, 06 Jul 2017 01:31:44 +0000
> > schrieb Moritz Maxeiner <moritz at ucworks.org>:
> >  
> >> But to be clear (and the title and description of any DIP
> >> addressing this should reflect this):
> >> These are not checked exceptions, because checked exceptions
> >> would require bar to declare its exception set manually.  
> >
> > Yep, absolutely clear. Just like "auto a = 1" does not declare
> > a variable as we all know declarations start with a type.  
> 
> Red herring.
> […]
> 
> ---
> void foo() throws AExp throws BExc { ... }
> void bar1() { foo(); } // Checked exceptions require this to 
> result in a compilation error
> void bar2() throws AExc throws BExc { foo(); } // this must be 
> used for checked exceptions
> ---

You are right, it was a red herring. The code example makes it
very obvious that inference means letting the exceptions slip
through unchecked and out of main() in the wildest case.

> Invalid premise. The definition of checked exceptions is de facto 
> fixed by Java [1], because it not only coined the term but 
> remains the only major PL to use them.

That's right, but still one can distill general ideas and
leave implementations details aside. Pretty much like the
Platonic Ideal. Then you look at what the complaints are with
the current implementation and see if you can satisfy all
sides.

I don't know if this is any good beyond an example of a
different implementation of checked exceptions, but here is
one option against the "every function in the call chain
accumulates more and more 'throws' declarations":

  /**
   * Throws:
   *   ZeroException when i is 0
   *   NonZeroException when i is not 0
   */
  void foo(int i) {
    if (i == 0) throw new ZeroException();
    throw new NonZeroException();
  }

  void bar(int i) @check_exceptions {
    foo(i);  // Error: The following exceptions are not
  handled:
             //     ZeroException thrown from foo() when i is 0
             //     NonZeroException thrown from foo() when i is not 0
  }

I.e. everything stays the same until a programmer needs a
verification of what (s)he should/could handle right away,
what needs to be wrapped and what can be passed further up the
call chain. That's close to impossible now in deeply nested
code.

Resource unavailability prone to race conditions can often be
handled by asking the user to fix the issue and continue for
example (including network, disk space, RAM, video encoding
hardware slots, exclusive microphone use).

In other cases an exception is only thrown when an incorrect
argument is passed. Knowing (statically) that you pass only
good values you can catch the exception and turn it into an
assert instead of passing it up the call chain, potentially
allowing the caller to be nothrow.
-- 
Marco



More information about the Digitalmars-d mailing list