www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Conclusions of the exception discussion

reply Jonathan M Davis <jmdavisProg gmx.com> writes:
Okay, the "The Right Approach to Exceptions" thread is a huge, confusing mess 
at this point without a clear, definitive conclusion, and we need one. So, I'm 
posting here, in a new thread, what appears to me to be the conclusion that 
that thread comes to and see if we can get some sort of consensus on this.

There are three things that that thread appears to conclude that we should do 
to improve the current situation with exceptions in Phobos and in D in 
general:

1. Phobos' exceptions should be reorganized into a class hierarchy designed 
such that the exceptions can be reusable outside of Phobos. We will no longer 
follow the policy of an exception per modules. A module may declare 0 to many 
exceptions depending on the problems that it would be reporting by throwing 
exceptions, and some modules will reuse the exceptions from other modules 
where appropriate.

The exact set of exceptions that we're going to end up with and how the 
hierarchy will be laid out has yet to be determined. It may or may not be 
similar to what Java and C# have. We will probably look at what they have as 
examples but will do whatever we decide works best for D and Phobos, and that 
may or may not have any relation to what those languages do. This will likely 
start with a minimal number of exceptions and will grow as necessary rather 
than trying to create a lot of exception types up front which we may not ever 
need. Regardless, we may know that we want a hierarchy, but the exact 
hierarchy has yet to be determined.


2. We should add a feature to the language to make it possible to catch 
multiple exception types with a single catch statement. There are two 
suggestions.

A. Do something similar to what Java 7 is doing and make it possible to simply 
list the exceptions that a particular catch statement accepts. That catch 
block will then catch any of the matching exceptions, and the type of the 
variable will be their most derived common type. One possible syntax would be

catch(e : Ex1, Ex2, Ex3) {}

B. Make it possible to add a condition which would be run when the catch 
statements are processed to allow you to catch based on other stuff in addition 
to the type. The condition would be a condition run at runtime rather than a 
compile time condition like template constraints. e.g.

catch(MyException e) if(e.prop == value) {}

It is unclear which we want to do or whether we want to do both. So, that 
still needs to be discussed further. But it's fairly clear that the majority 
want a feature along the lines of one or both of those two suggestions. 
However, regardless of which we choose, someone is going to have to take the 
time to implement it, since odds are that Walter isn't going to do it. So, 
whether we end up with a feature along these lines is highly dependent on 
whether anyone is willing to take the time to implement it and get it accepted 
by Walter.


3. We should add a Variant[string] property to Exception. Every derived class 
will then populate it with the values of its member variables in their 
constructors, and code outside of the exception classes can choose to insert 
other values into the table which are useful for the particular programs that 
they're in but which don't make sense to put in the exception types 
themselves.

A free function will then be designed and implemented which will take some 
kind of format string along with an exception and will then allow you to 
generate a message from that exception using whatever formatting you want 
using the hash table to generically obtain the values from the exception 
without needing to catch or know the exact type of the exception. e.g.

catch(Exception e)
{
    writeln(magicFormattingFunction(formatStr, e));
}

This Variant[string] property would _not_ replace having direct member 
variables in derived exceptions. Rather, it would allow us to make sure that 
we only put member variables in derived exceptions when they belong there, and 
code which wants additional data but not a new exception type can use the hash 
table to hold it. And of course, it also gives us the foundation to build the 
fancier string formatting capabalities.


There were other ideas that were discussed in the thread, but I think that 
these are the ones that we have at least some consensus on. However, given the 
mess that thread is, we really should make it clear in a separate thread (this 
thread) that we have a consensus that these are indeed the things that we want 
to pursue to improve exceptions in D and Phobos. Thoughts? Opinions?

- Jonathan M Davis
Feb 24 2012
next sibling parent reply "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.93.1330149312.24984.digitalmars-d puremagic.com...
 However, regardless of which we choose, someone is going to have to take 
 the
 time to implement it, since odds are that Walter isn't going to do it. So,
 whether we end up with a feature along these lines is highly dependent on
 whether anyone is willing to take the time to implement it and get it 
 accepted
 by Walter.

Waaaay ahead of you here. https://github.com/D-Programming-Language/dmd/pull/738 It's currently 'catch(auto e : E1, E2, E3)' but changing the syntax is trivial if everyone decides they want it.
Feb 24 2012
next sibling parent reply deadalnix <deadalnix gmail.com> writes:
Le 25/02/2012 07:26, Daniel Murphy a écrit :
 "Jonathan M Davis"<jmdavisProg gmx.com>  wrote in message
 news:mailman.93.1330149312.24984.digitalmars-d puremagic.com...
 However, regardless of which we choose, someone is going to have to take
 the
 time to implement it, since odds are that Walter isn't going to do it. So,
 whether we end up with a feature along these lines is highly dependent on
 whether anyone is willing to take the time to implement it and get it
 accepted
 by Walter.

Waaaay ahead of you here. https://github.com/D-Programming-Language/dmd/pull/738 It's currently 'catch(auto e : E1, E2, E3)' but changing the syntax is trivial if everyone decides they want it.

I do think this approach have a flaw. If we go in that direction, then it push devs to create new Exception type just to catch them, because this is the only way we have. If I understand properly your pull request, the compiler will be duplicating catch block ? If it is the case, would it be possible to use static if to use type specific stuff of E1, E2 or E3, depending on which one we are facing ? BTW, great job, it is definitively a nice addition to have. jmdavis > good job to synthetize all this. I think you get the most importants points of the talk.
Feb 25 2012
parent reply "Daniel Murphy" <yebblies nospamgmail.com> writes:
"deadalnix" <deadalnix gmail.com> wrote in message 
news:jiagbg$liu$1 digitalmars.com...
 Le 25/02/2012 07:26, Daniel Murphy a écrit :
 https://github.com/D-Programming-Language/dmd/pull/738

I do think this approach have a flaw. If we go in that direction, then it push devs to create new Exception type just to catch them, because this is the only way we have.

This is a different issue to whether or not we have the syntax to catch multiple exceptions with a single catch block.
 If I understand properly your pull request, the compiler will be 
 duplicating catch block ? If it is the case, would it be possible to use 
 static if to use type specific stuff of E1, E2 or E3, depending on which 
 one we are facing ?

No, it just creates stub catch blocks that jump to the real one. Duplicating the blocks would have weird effects on things like static variables. I think that kind of code duplication is better done with something that works like mixing in case statements. catch(auto e : E1, E2) { body; } -> catch(E1 e) { goto catchE2; } catch(E2 e) { catchE2: body; }
Feb 25 2012
next sibling parent reply deadalnix <deadalnix gmail.com> writes:
Le 25/02/2012 14:11, Daniel Murphy a écrit :
 "deadalnix"<deadalnix gmail.com>  wrote in message
 news:jiagbg$liu$1 digitalmars.com...
 Le 25/02/2012 07:26, Daniel Murphy a �crit :
 https://github.com/D-Programming-Language/dmd/pull/738

I do think this approach have a flaw. If we go in that direction, then it push devs to create new Exception type just to catch them, because this is the only way we have.

This is a different issue to whether or not we have the syntax to catch multiple exceptions with a single catch block.
 If I understand properly your pull request, the compiler will be
 duplicating catch block ? If it is the case, would it be possible to use
 static if to use type specific stuff of E1, E2 or E3, depending on which
 one we are facing ?

No, it just creates stub catch blocks that jump to the real one. Duplicating the blocks would have weird effects on things like static variables. I think that kind of code duplication is better done with something that works like mixing in case statements. catch(auto e : E1, E2) { body; } -> catch(E1 e) { goto catchE2; } catch(E2 e) { catchE2: body; }

Wow, it didn't got that. This is nice, but then, the Exception type is completely lost. It does means that we are not interested in the Exception type, but of its presence, and so, maybe we just have created useless Exception types and this has to be fixed instead of the language ?
Feb 25 2012
parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"deadalnix" <deadalnix gmail.com> wrote in message news:jib71o$1v05
 Wow, it didn't got that. This is nice, but then, the Exception type is 
 completely lost.

 It does means that we are not interested in the Exception type, but of its 
 presence, and so, maybe we just have created useless Exception types and 
 this has to be fixed instead of the language ?

I don't expect to solve every issue with exceptions with this patch. The main use is for when a set of different exceptions need to be handled the same way, but the common supertype includes other exceptions you don't want to catch. Eg. you might want to catch three types of FileException and two types of SocketException and do some common error handling, but don't want to catch _every_ type of either, or the entire IOException tree. If you want to access specific data from a subclass, make a different catch block for it, or downcast.
Feb 25 2012
prev sibling parent reply kennytm <kennytm gmail.com> writes:
"Daniel Murphy" <yebblies nospamgmail.com> wrote:
 "deadalnix" <deadalnix gmail.com> wrote in message 
 news:jiagbg$liu$1 digitalmars.com...
 Le 25/02/2012 07:26, Daniel Murphy a Ècrit :
 https://github.com/D-Programming-Language/dmd/pull/738

I do think this approach have a flaw. If we go in that direction, then it push devs to create new Exception type just to catch them, because this is the only way we have.

This is a different issue to whether or not we have the syntax to catch multiple exceptions with a single catch block.
 If I understand properly your pull request, the compiler will be 
 duplicating catch block ? If it is the case, would it be possible to use 
 static if to use type specific stuff of E1, E2 or E3, depending on which 
 one we are facing ?
 

No, it just creates stub catch blocks that jump to the real one. Duplicating the blocks would have weird effects on things like static variables. I think that kind of code duplication is better done with something that works like mixing in case statements. catch(auto e : E1, E2) { body; } -> catch(E1 e) { goto catchE2; } catch(E2 e) { catchE2: body; }

Won't work unless the compiler enforce that 'body' does not use code which requires typeof(e) == E2.
Feb 25 2012
parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"kennytm" <kennytm gmail.com> wrote in message 
news:1711314076351895446.251635kennytm-gmail.com news.digitalmars.com...
 catch(auto e : E1, E2) { body; }
 ->

 catch(E1 e)
 {
   goto catchE2;
 }
 catch(E2 e)
 {
 catchE2:
   body;
 }

Won't work unless the compiler enforce that 'body' does not use code which requires typeof(e) == E2.

Ok, I oversimplified it a bit. It's more like this: __set_except_list(); trybody(); goto __try_break; __exceptionE1: goto __exceptionE2; __exceptionE2: catchbody(); goto __try_break; __try_break: And when semantic is run on catchbody, the type of the variable is set to the common supertype of all the exceptions in the list.
Feb 25 2012
prev sibling parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Martin Nowak" <dawg dawgfoto.de> wrote in message 
news:op.v98ik4hysqugbd dawg-freebsd.lan...
 It's currently 'catch(auto e : E1, E2, E3)' but changing the syntax is
 trivial if everyone decides they want it.


That's a very good idea.
 The exception types (E1, E2, E3) should expand TypeTuples similar to how 
 you
 declare base classes.

Oops, I meant to do this and completely forgot.
 As for the syntax how about '=' assigning a catched exception.
 catch(IOException io = E1, E2, E3)
 catch(auto io = E1, E2, E3)

That syntax (sort of) already means declare variables io, E2 and E3.
 The colon is used for type conversions, where left implicitly converts to 
 right.
 catch(E1, E2, E3 : IOException io)
 catch(E1, E2, E3 : auto io)

And that looks like three template arguments, sorta... The syntax I've implemented was 'inspired' by the base class list syntax. When base class protection is removed it could even use the same parsing function. It's listing derived classes, not base classes, but this is the closest thing in D syntax I could find. It also works with typetuples in the same way. But anyway, I'll implement whatever gets W approval.
Feb 25 2012
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, February 25, 2012 17:26:02 Daniel Murphy wrote:
 "Jonathan M Davis" <jmdavisProg gmx.com> wrote in message
 news:mailman.93.1330149312.24984.digitalmars-d puremagic.com...
 
 However, regardless of which we choose, someone is going to have to take
 the
 time to implement it, since odds are that Walter isn't going to do it. So,
 whether we end up with a feature along these lines is highly dependent on
 whether anyone is willing to take the time to implement it and get it
 accepted
 by Walter.

Waaaay ahead of you here. https://github.com/D-Programming-Language/dmd/pull/738 It's currently 'catch(auto e : E1, E2, E3)' but changing the syntax is trivial if everyone decides they want it.

Whoa. Are trying to be the next Kenji Hara? ;) It's definitely nice to have some solid, prolific contributors to the compiler. - Jonathan M Davis
Feb 24 2012
parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.94.1330151556.24984.digitalmars-d puremagic.com...
 On Saturday, February 25, 2012 17:26:02 Daniel Murphy wrote:
 "Jonathan M Davis" <jmdavisProg gmx.com> wrote in message
 news:mailman.93.1330149312.24984.digitalmars-d puremagic.com...

 However, regardless of which we choose, someone is going to have to 
 take
 the
 time to implement it, since odds are that Walter isn't going to do it. 
 So,
 whether we end up with a feature along these lines is highly dependent 
 on
 whether anyone is willing to take the time to implement it and get it
 accepted
 by Walter.

Waaaay ahead of you here. https://github.com/D-Programming-Language/dmd/pull/738 It's currently 'catch(auto e : E1, E2, E3)' but changing the syntax is trivial if everyone decides they want it.

Whoa. Are trying to be the next Kenji Hara? ;) It's definitely nice to have some solid, prolific contributors to the compiler. - Jonathan M Davis

Lol I've been around for a while.
Feb 25 2012
prev sibling next sibling parent reply Johannes Pfau <nospam example.com> writes:
Am Fri, 24 Feb 2012 21:53:47 -0800
schrieb Jonathan M Davis <jmdavisProg gmx.com>:

 There were other ideas that were discussed in the thread, but I think
 that these are the ones that we have at least some consensus on.
 However, given the mess that thread is, we really should make it
 clear in a separate thread (this thread) that we have a consensus
 that these are indeed the things that we want to pursue to improve
 exceptions in D and Phobos. Thoughts? Opinions?
 
 - Jonathan M Davis

What about that lisp exception/recovery idea? That was the most interesting idea imho.
Feb 25 2012
parent deadalnix <deadalnix gmail.com> writes:
Le 25/02/2012 10:11, Johannes Pfau a écrit :
 Am Fri, 24 Feb 2012 21:53:47 -0800
 schrieb Jonathan M Davis<jmdavisProg gmx.com>:

 There were other ideas that were discussed in the thread, but I think
 that these are the ones that we have at least some consensus on.
 However, given the mess that thread is, we really should make it
 clear in a separate thread (this thread) that we have a consensus
 that these are indeed the things that we want to pursue to improve
 exceptions in D and Phobos. Thoughts? Opinions?

 - Jonathan M Davis

What about that lisp exception/recovery idea? That was the most interesting idea imho.

This idea is very interesting, but we must separate it from the Exception issue. For separation of concerns, let's build this on top of the Exception system.
Feb 25 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, February 25, 2012 10:11:56 Johannes Pfau wrote:
 Am Fri, 24 Feb 2012 21:53:47 -0800
 
 schrieb Jonathan M Davis <jmdavisProg gmx.com>:
 There were other ideas that were discussed in the thread, but I think
 that these are the ones that we have at least some consensus on.
 However, given the mess that thread is, we really should make it
 clear in a separate thread (this thread) that we have a consensus
 that these are indeed the things that we want to pursue to improve
 exceptions in D and Phobos. Thoughts? Opinions?
 
 - Jonathan M Davis

What about that lisp exception/recovery idea? That was the most interesting idea imho.

There's no consensus whatsoever on using that. It's just a new, interesting idea at this point, and it's incredibly experimental. Some folks are playing around with it right now, but until they've ironed it out, there's not much point in discussing whether we should add it to Phobos IMHO. It's also something that we can add on top of the current exception scheme at a later date, so we don't have to do anything with it now. We'll have to give it more bake time before we make any decisions about it. And I believe that the main proponents of it agree with that assessment. - Jonathan M Davis
Feb 25 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, February 25, 2012 21:12:51 Daniel Murphy wrote:
 Lol I've been around for a while.

I know. But particularly over the last few months, you seem to be doing a lot. - Jonathan M Davis
Feb 25 2012
prev sibling next sibling parent reply Kevin Cox <kevincox.ca gmail.com> writes:
--0015174be384a83ecd04b9c90546
Content-Type: text/plain; charset=UTF-8

I think there should also be multiple catches so that you can deal with
different exceptions different ways without trying to upcast them over and
over again.
On Feb 25, 2012 1:30 AM, "Daniel Murphy" <yebblies nospamgmail.com> wrote:

 "Jonathan M Davis" <jmdavisProg gmx.com> wrote in message
 news:mailman.93.1330149312.24984.digitalmars-d puremagic.com...
 However, regardless of which we choose, someone is going to have to take
 the
 time to implement it, since odds are that Walter isn't going to do it.

 whether we end up with a feature along these lines is highly dependent on
 whether anyone is willing to take the time to implement it and get it
 accepted
 by Walter.

Waaaay ahead of you here. https://github.com/D-Programming-Language/dmd/pull/738 It's currently 'catch(auto e : E1, E2, E3)' but changing the syntax is trivial if everyone decides they want it.

--0015174be384a83ecd04b9c90546 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p>I think there should also be multiple catches so that you can deal with = different exceptions different ways without trying to upcast them over and = over again.</p> <div class=3D"gmail_quote">On Feb 25, 2012 1:30 AM, &quot;Daniel Murphy&quo= t; &lt;<a href=3D"mailto:yebblies nospamgmail.com">yebblies nospamgmail.com= </a>&gt; wrote:<br type=3D"attribution"><blockquote class=3D"gmail_quote" s= tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> &quot;Jonathan M Davis&quot; &lt;<a href=3D"mailto:jmdavisProg gmx.com">jmd= avisProg gmx.com</a>&gt; wrote in message<br> news:mailman.93.1330149312.24984.digitalmars-d puremagic.com...<br> &gt; However, regardless of which we choose, someone is going to have to ta= ke<br> &gt; the<br> &gt; time to implement it, since odds are that Walter isn&#39;t going to do= it. So,<br> &gt; whether we end up with a feature along these lines is highly dependent= on<br> &gt; whether anyone is willing to take the time to implement it and get it<= br> &gt; accepted<br> &gt; by Walter.<br> <br> Waaaay ahead of you here.<br> <br> <a href=3D"https://github.com/D-Programming-Language/dmd/pull/738" target= =3D"_blank">https://github.com/D-Programming-Language/dmd/pull/738</a><br> <br> It&#39;s currently &#39;catch(auto e : E1, E2, E3)&#39; but changing the sy= ntax is<br> trivial if everyone decides they want it.<br> <br> <br> </blockquote></div> --0015174be384a83ecd04b9c90546--
Feb 25 2012
parent "Daniel Murphy" <yebblies nospamgmail.com> writes:
Content-Type: text/plain;
	charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Could you give a code example of what you mean?  You can still use =
multiple catch blocks perfectly well with this patch.
  "Kevin Cox" <kevincox.ca gmail.com> wrote in message =
news:mailman.97.1330172953.24984.digitalmars-d puremagic.com...
  I think there should also be multiple catches so that you can deal =
with different exceptions different ways without trying to upcast them =
over and over again.

  On Feb 25, 2012 1:30 AM, "Daniel Murphy" <yebblies nospamgmail.com> =
wrote:

    "Jonathan M Davis" <jmdavisProg gmx.com> wrote in message
    news:mailman.93.1330149312.24984.digitalmars-d puremagic.com...
    > However, regardless of which we choose, someone is going to have =
to take
    > the
    > time to implement it, since odds are that Walter isn't going to do =
it. So,
    > whether we end up with a feature along these lines is highly =
dependent on
    > whether anyone is willing to take the time to implement it and get =
it
    > accepted
    > by Walter.

    Waaaay ahead of you here.

    https://github.com/D-Programming-Language/dmd/pull/738

    It's currently 'catch(auto e : E1, E2, E3)' but changing the syntax =
is
    trivial if everyone decides they want it.
Feb 25 2012
prev sibling next sibling parent "Martin Nowak" <dawg dawgfoto.de> writes:
 It's currently 'catch(auto e : E1, E2, E3)' but changing the syntax is
 trivial if everyone decides they want it.

The exception types (E1, E2, E3) should expand TypeTuples similar to how you declare base classes. alias TypeTuple!(SocketTimeOut, SocketFooBar) SocketExceptions; try { bind(...); listen(...); } catch (IOException io : SocketExceptions) { } As for the syntax how about '=' assigning a catched exception. catch(IOException io = E1, E2, E3) catch(auto io = E1, E2, E3) The colon is used for type conversions, where left implicitly converts to right. catch(E1, E2, E3 : IOException io) catch(E1, E2, E3 : auto io)
Feb 25 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, February 25, 2012 07:29:01 Kevin Cox wrote:
 I think there should also be multiple catches so that you can deal with
 different exceptions different ways without trying to upcast them over and
 over again.

You can do that now. Just catch each specific exception type that you want to catch. The issue is when you want to catch a specific set of exceptions and treat them all the same, but you don't want to treat all exceptions of their common type the same. catch(e : UTFException, UnicodeException) { } catch(StringException e) { } catch(Exception e) { } Presently, the only common type that UTFException and UnicodeException share is Exception. So, if we didn't have a syntax like I use above (which we currently don't have), if either have to catch UTFException and UnicodeException separately and duplicate the code within the catch block for each of them (though you could use a mixin or a function to reduce the duplication), or you'd have to catch Exception, and then do something like catch(Exception e) { if(cast(UTFException)e || cast(UnicodeException)e) { } else if(cast(StringException)e) { } else { } } That's far uglier and is completely unable to take advantage of catch's ability to catch by type. Also, what if you didn't really want to catch Exception? e.g. catch(e : UTFException, UnicodeException) { } catch(StringException e) { } Then, if you went to catch Exception, because it was the common type, you'd have to rethrow the exception if it wasn't one of the 3 that you cared about, which resets the stack trace. _That_ is the problem that this is trying to solve. If you really want to catch exceptions individulally by their specific types, then you can already do that just fine. - Jonathan M Davis
Feb 25 2012
prev sibling next sibling parent "Kagamin" <spam here.lot> writes:
On Saturday, 25 February 2012 at 23:32:24 UTC, Jonathan M Davis 
wrote:
 which resets the stack trace.

This is the issue, you're trying to address with these proposals?
Feb 26 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, February 26, 2012 12:24:09 Kagamin wrote:
 On Saturday, 25 February 2012 at 23:32:24 UTC, Jonathan M Davis
 
 wrote:
 which resets the stack trace.

This is the issue, you're trying to address with these proposals?

It's _an_ issue, not the only issue. The bigger issue there is that you're forced to duplicate catch blocks when you want to catch several disparate exceptions and handle them identically (either that, or you're forced to catch their base type and examine their actual types individually). The stack trace part may even end up being fixed by changing the rethrowing behavior. It's just one of the things that would be affected by making it possible to catch disparate exceptions with the same catch block. It's not the primary thing. As for the exception hierarchy or Variant[string] stuff, that has _nothing_ to do with resetting the stack trace. They solve completely different issues. - Jonathan M Davis
Feb 26 2012
prev sibling next sibling parent reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Jonathan M Davis wrote:
 Okay, the "The Right Approach to Exceptions" thread is a huge, confusing mess
 at this point without a clear, definitive conclusion, and we need one. So, I'm
 posting here, in a new thread, what appears to me to be the conclusion that
 that thread comes to and see if we can get some sort of consensus on this.

 There are three things that that thread appears to conclude that we should do
 to improve the current situation with exceptions in Phobos and in D in
 general:

 1. Phobos' exceptions should be reorganized into a class hierarchy designed
 such that the exceptions can be reusable outside of Phobos. We will no longer
 follow the policy of an exception per modules. A module may declare 0 to many
 exceptions depending on the problems that it would be reporting by throwing
 exceptions, and some modules will reuse the exceptions from other modules
 where appropriate.

 The exact set of exceptions that we're going to end up with and how the
 hierarchy will be laid out has yet to be determined. It may or may not be
 similar to what Java and C# have. We will probably look at what they have as
 examples but will do whatever we decide works best for D and Phobos, and that
 may or may not have any relation to what those languages do. This will likely
 start with a minimal number of exceptions and will grow as necessary rather
 than trying to create a lot of exception types up front which we may not ever
 need. Regardless, we may know that we want a hierarchy, but the exact
 hierarchy has yet to be determined.

This is what I like to see.
 2. We should add a feature to the language to make it possible to catch
 multiple exception types with a single catch statement. There are two
 suggestions.

 A. Do something similar to what Java 7 is doing and make it possible to simply
 list the exceptions that a particular catch statement accepts. That catch
 block will then catch any of the matching exceptions, and the type of the
 variable will be their most derived common type. One possible syntax would be

 catch(e : Ex1, Ex2, Ex3) {}

 B. Make it possible to add a condition which would be run when the catch
 statements are processed to allow you to catch based on other stuff in addition
 to the type. The condition would be a condition run at runtime rather than a
 compile time condition like template constraints. e.g.

 catch(MyException e) if(e.prop == value) {}

 It is unclear which we want to do or whether we want to do both. So, that
 still needs to be discussed further. But it's fairly clear that the majority
 want a feature along the lines of one or both of those two suggestions.
 However, regardless of which we choose, someone is going to have to take the
 time to implement it, since odds are that Walter isn't going to do it. So,
 whether we end up with a feature along these lines is highly dependent on
 whether anyone is willing to take the time to implement it and get it accepted
 by Walter.

Please do not do that. It will introduce additional set of bugs and increase maintaining effort for the sake of small syntactic sugar improvements. I think current exception handling style is enough. Its successively used in C# for years. If one wants to catch more than one exception in one handler, she just catches the first common base class such as Exception and then tests for concrete derived class inside catch handler: catch (Exception e) { if (cast(MyException1)e) { // catch MyException1 } else if (cast(MyException2)e) { // catch MyException2 } else throw; } I see nothing difficult in that.
 3. We should add a Variant[string] property to Exception. Every derived class
 will then populate it with the values of its member variables in their
 constructors, and code outside of the exception classes can choose to insert
 other values into the table which are useful for the particular programs that
 they're in but which don't make sense to put in the exception types
 themselves.

 A free function will then be designed and implemented which will take some
 kind of format string along with an exception and will then allow you to
 generate a message from that exception using whatever formatting you want
 using the hash table to generically obtain the values from the exception
 without needing to catch or know the exact type of the exception. e.g.

 catch(Exception e)
 {
      writeln(magicFormattingFunction(formatStr, e));
 }

 This Variant[string] property would _not_ replace having direct member
 variables in derived exceptions. Rather, it would allow us to make sure that
 we only put member variables in derived exceptions when they belong there, and
 code which wants additional data but not a new exception type can use the hash
 table to hold it. And of course, it also gives us the foundation to build the
 fancier string formatting capabalities.

Please no (sorry Andrei). This whole idea comes from the fact that deriving a class like this: class MyException : Exception { } adds code bloat to executable. This is mostly an implementation issue of classes as a whole and I don't like to fix implementation issues by introducing not D'ish style to something as fundamental as exceptions. Imagine those hundreds of newcomers saying "WTF, why not just derive from base exception class?".
 There were other ideas that were discussed in the thread, but I think that
 these are the ones that we have at least some consensus on. However, given the
 mess that thread is, we really should make it clear in a separate thread (this
 thread) that we have a consensus that these are indeed the things that we want
 to pursue to improve exceptions in D and Phobos. Thoughts? Opinions?

Why there is code bloat at all? Why full RTTI for a class is generated when I don't want to? I know that some bare minimum must be generated for virtual function, dynamic casts and interface support. But why can't it be done more compact? Deriving a class without adding a single member should add *minimal* number of bytes to executable, not a code bloat! What if I don't need RTTI at all, when I don't use typeid(), casts, virtual functions and interfaces? I explained some eventual improvements in this post: http://forum.dlang.org/post/ji0i7p$2mck$1 digitalmars.com
Feb 26 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 02/26/2012 07:46 PM, Piotr Szturmaj wrote:
 Please do not do that. It will introduce additional set of bugs and
 increase maintaining effort for the sake of small syntactic sugar
 improvements. I think current exception handling style is enough. Its
 successively used in C# for years.

Do you realize that syntactic sugar improvements are trivial to implement (just re-write the AST a little), and have almost no influence on the existing code base?
Feb 26 2012
next sibling parent Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Timon Gehr wrote:
 On 02/26/2012 07:46 PM, Piotr Szturmaj wrote:
 Please do not do that. It will introduce additional set of bugs and
 increase maintaining effort for the sake of small syntactic sugar
 improvements. I think current exception handling style is enough. Its
 successively used in C# for years.

Do you realize that syntactic sugar improvements are trivial to implement (just re-write the AST a little), and have almost no influence on the existing code base?

I didn't know that, I was just a bit sceptical. If they're really trivial then I see no reason they couldn't be made.
Feb 26 2012
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Timon Gehr:

 Do you realize that syntactic sugar improvements are trivial to 
 implement (just re-write the AST a little), and have almost no influence 
 on the existing code base?

In my opinion it's good to have a syntax to catch a many exceptions "at once". But this is yet another special syntax case for a sequence of things, where instead a built-in tuple syntax is more uniform and better. Tuples are a data structure more fundamental and more important than associative arrays. In Python this syntax caused troubles: http://www.python.org/dev/peps/pep-3110/ Bye, bearophile
Feb 26 2012
prev sibling parent Don <nospam nospam.com> writes:
On 25.02.2012 06:53, Jonathan M Davis wrote:
 Okay, the "The Right Approach to Exceptions" thread is a huge, confusing mess
 at this point without a clear, definitive conclusion, and we need one. So, I'm
 posting here, in a new thread, what appears to me to be the conclusion that
 that thread comes to and see if we can get some sort of consensus on this.

 There are three things that that thread appears to conclude that we should do
 to improve the current situation with exceptions in Phobos and in D in
 general:

 1. Phobos' exceptions should be reorganized into a class hierarchy designed
 such that the exceptions can be reusable outside of Phobos. We will no longer
 follow the policy of an exception per modules. A module may declare 0 to many
 exceptions depending on the problems that it would be reporting by throwing
 exceptions, and some modules will reuse the exceptions from other modules
 where appropriate.

 The exact set of exceptions that we're going to end up with and how the
 hierarchy will be laid out has yet to be determined. It may or may not be
 similar to what Java and C# have. We will probably look at what they have as
 examples but will do whatever we decide works best for D and Phobos, and that
 may or may not have any relation to what those languages do. This will likely
 start with a minimal number of exceptions and will grow as necessary rather
 than trying to create a lot of exception types up front which we may not ever
 need. Regardless, we may know that we want a hierarchy, but the exact
 hierarchy has yet to be determined.


 2. We should add a feature to the language to make it possible to catch
 multiple exception types with a single catch statement. There are two
 suggestions.

 A. Do something similar to what Java 7 is doing and make it possible to simply
 list the exceptions that a particular catch statement accepts. That catch
 block will then catch any of the matching exceptions, and the type of the
 variable will be their most derived common type. One possible syntax would be

 catch(e : Ex1, Ex2, Ex3) {}

 B. Make it possible to add a condition which would be run when the catch
 statements are processed to allow you to catch based on other stuff in addition
 to the type. The condition would be a condition run at runtime rather than a
 compile time condition like template constraints. e.g.

 catch(MyException e) if(e.prop == value) {}

The difficulty with that sort of thing, is that the stack is in a transitory state while it's working out which exception to catch, and the 'e' variable doesn't quite exist yet. I wrote the exception chaining implementation for Windows, and what I found interesting is that Windows SEH works rather like that. Each function with a catch handler gets called, and (roughly) returns a bool saying if it do the catch. There really aren't any rules for what that function can do, there's absolutely no reason for it to be type-based. In fact using type-matching seems quite odd, in C++ it's one of the very few built-in things which uses run-time type info. I think that any pure function could be used instead.
Mar 02 2012