www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - exception inheritance proposal

reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
Over the past few days/weeks I've been going over the phobos exception 
usage. Below is my proposal for modifying the phobos exception class 
inheritance hierarchy (indenting indicates subclassing). I have no idea if 
Walter would actually accept anything close to this proposal, but I figure 
what the heck. See notes and questions at the end, too.

Object
   OutOfMemory
   AssertionFailure (was AssertError:Error)
      NoSwitchDefault (was SwitchError:Error)
   Exception
      ParamException (new)
         ParamNullException (new)
         ParamRangeException (new)
      IndexException (new)
         ArrayBoundsException (was ArrayBoundsError:Error)
      CollectionCopyException (new)
         ArrayCopyException (was Error in internal/arraycat.d)
      NotSupportedException (new)
      NotImplementedException (new)
      AddressException
      Base64Exception
         Base64CharException
      CastException (new)
         ArrayCastException (was Error in internal/arraycast.d)
      ConvException (was ConvError:Error)
         ConvOverflowException (was ConvOverflowError:ConvError)
      DateParseException (was DateParseError:Error)
      SystemError (see Regan's code posted on thread about std.syserror)
         FileException (was FileException:Exception)
         SocketException (was SocketException:Exception)
            SocketAcceptException
         HostException (was HostException:Exception)
         RegistryException (was RegistryException:Win32Exception)
         ExeModuleException (was ExeModuleException:Exception)
      FormatException (was FormatError:Error)
      ModuleCtorException (was ModuleCtorError:Exception)
      OpenRJException
         DatabaseException
         InvalidKeyException
         InvalidTypeException
      RegExpException (was RegExpError:Error)
      StreamException
         ReadException
         WriteException
         SeekException
         StreamFileException
            OpenException
      StringException
      ThreadException (was ThreadError:Error)
         OutOfThreadsException (new)
      URIException (was URIError:Error)
      UTFException (was UtfError:Error)
      ZipException
      ZlibException

Notes:
1. removed std.windows.registry.Win32Exception since it overlaps with
     SystemError for Windows
2. remove FooError aliases for std.stream exceptions
3. some exceptions might be thrown with SystemError causes
     (eg StreamFileException, ThreadException)
4. RegistryException is thrown once without a system error code
5. NotSupportedException will be a cause in
     - std.mmfile some thrown FileExceptions
     - std.stream in a StreamException that replaces a raw Exception
     - std.zip in several ZipExceptions
6. Backwards incompatibilities are limited (hopefully) to class names 
involving Error
   and subclassing Error. The subclassing Error switches to Exception except
   for asserts and switch defaults don't subclass Exception in the new 
scheme.
7. The array errors now subclass general reusable errors.

Exception is defined as
class Exception {
    char[] msg;
    Object cause; // new

    this(char[] msg, Object cause = null) { // new
        this.msg = msg;
        this.cause = cause; // new
    }

    void print() {
        printf("%.*s\n", msg);
        if (cause) cause.print(); // new
    }

    char[] toString() { return msg; }
}

For the definition of SystemError see Regan's post 
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21282

Questions:
1. what should the top few lines of the hierarchy look like?
2. should modules that currently reuse one exception create subclasses?
3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
     throw a raw Exception)
4. what is missing? 
Apr 13 2005
next sibling parent reply "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
I don't much care about the leaf-side hierarchy, as I think the root 
is far more important. I'm a bit surprised to see that you've stuck 
with Object as the common base of the hierarchy. What is the reason 
behind that, given that the impression from the recent discussions 
has been, IME, that most wanted a change?

"Ben Hinkle" <ben.hinkle gmail.com> wrote in message 
news:d3kkph$2t76$1 digitaldaemon.com...
 Over the past few days/weeks I've been going over the phobos 
 exception usage. Below is my proposal for modifying the phobos 
 exception class inheritance hierarchy (indenting indicates 
 subclassing). I have no idea if Walter would actually accept 
 anything close to this proposal, but I figure what the heck. See 
 notes and questions at the end, too.

 Object
   OutOfMemory
   AssertionFailure (was AssertError:Error)
      NoSwitchDefault (was SwitchError:Error)
   Exception
      ParamException (new)
         ParamNullException (new)
         ParamRangeException (new)
      IndexException (new)
         ArrayBoundsException (was ArrayBoundsError:Error)
      CollectionCopyException (new)
         ArrayCopyException (was Error in internal/arraycat.d)
      NotSupportedException (new)
      NotImplementedException (new)
      AddressException
      Base64Exception
         Base64CharException
      CastException (new)
         ArrayCastException (was Error in internal/arraycast.d)
      ConvException (was ConvError:Error)
         ConvOverflowException (was ConvOverflowError:ConvError)
      DateParseException (was DateParseError:Error)
      SystemError (see Regan's code posted on thread about 
 std.syserror)
         FileException (was FileException:Exception)
         SocketException (was SocketException:Exception)
            SocketAcceptException
         HostException (was HostException:Exception)
         RegistryException (was RegistryException:Win32Exception)
         ExeModuleException (was ExeModuleException:Exception)
      FormatException (was FormatError:Error)
      ModuleCtorException (was ModuleCtorError:Exception)
      OpenRJException
         DatabaseException
         InvalidKeyException
         InvalidTypeException
      RegExpException (was RegExpError:Error)
      StreamException
         ReadException
         WriteException
         SeekException
         StreamFileException
            OpenException
      StringException
      ThreadException (was ThreadError:Error)
         OutOfThreadsException (new)
      URIException (was URIError:Error)
      UTFException (was UtfError:Error)
      ZipException
      ZlibException

 Notes:
 1. removed std.windows.registry.Win32Exception since it overlaps 
 with
     SystemError for Windows
 2. remove FooError aliases for std.stream exceptions
 3. some exceptions might be thrown with SystemError causes
     (eg StreamFileException, ThreadException)
 4. RegistryException is thrown once without a system error code
 5. NotSupportedException will be a cause in
     - std.mmfile some thrown FileExceptions
     - std.stream in a StreamException that replaces a raw 
 Exception
     - std.zip in several ZipExceptions
 6. Backwards incompatibilities are limited (hopefully) to class 
 names involving Error
   and subclassing Error. The subclassing Error switches to 
 Exception except
   for asserts and switch defaults don't subclass Exception in the 
 new scheme.
 7. The array errors now subclass general reusable errors.

 Exception is defined as
 class Exception {
    char[] msg;
    Object cause; // new

    this(char[] msg, Object cause = null) { // new
        this.msg = msg;
        this.cause = cause; // new
    }

    void print() {
        printf("%.*s\n", msg);
        if (cause) cause.print(); // new
    }

    char[] toString() { return msg; }
 }

 For the definition of SystemError see Regan's post 
 http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21282

 Questions:
 1. what should the top few lines of the hierarchy look like?
 2. should modules that currently reuse one exception create 
 subclasses?
 3. when is it ok to just throw Exception? (ie - should 
 internal/gc/gc.d
     throw a raw Exception)
 4. what is missing?
 
Apr 13 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
news:d3kos2$2vnh$1 digitaldaemon.com...
I don't much care about the leaf-side hierarchy, as I think the root is far 
more important. I'm a bit surprised to see that you've stuck with Object as 
the common base of the hierarchy. What is the reason behind that, given 
that the impression from the recent discussions has been, IME, that most 
wanted a change?
Technically Object will always be the root as long as 'throw' can take Object. I should have put at the top of the post that I assume the language stays the same - if Walter changes what gets thrown then the root will change. I have no idea what Walter thinks of changing the root. So I proceeded given Object is the root, what should the next few branches be? I argue the depth of the tree should be kept as small as practical so that we don't end up with the random hierarchy like the current phobos and Java (ie - fewer decisions for class writers means fewer mistakes). The key is that the tree we have still needs to be useful and flexible. I see Object and Exception have enough exception-friendly features except for stack traces and perhaps other unknown features. If stack traces ever get introduced to D we could wedge in another branch of the tree but personally I'd prefer to do it though an interface implemented by Exception and (for argument's sake I'll assume my proposal) AssertionFailure (OutOfMemory makes me nervous wrt stack traces for reasons I posted in another thread: where does the memory for the stack trace come from?). That would keep the tree depth down while adding flexibility. Other features could be added to Exception and/or through interfaces. -Ben ps - what does IME mean?
Apr 13 2005
parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"Ben Hinkle" <ben.hinkle gmail.com> wrote in message 
news:d3ksf2$1vm$1 digitaldaemon.com...
 "Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message 
 news:d3kos2$2vnh$1 digitaldaemon.com...
I don't much care about the leaf-side hierarchy, as I think the 
root is far more important. I'm a bit surprised to see that you've 
stuck with Object as the common base of the hierarchy. What is the 
reason behind that, given that the impression from the recent 
discussions has been, IME, that most wanted a change?
Technically Object will always be the root as long as 'throw' can take Object. I should have put at the top of the post that I assume the language stays the same - if Walter changes what gets thrown then the root will change. I have no idea what Walter thinks of changing the root. So I proceeded given Object is the root, what should the next few branches be? I argue the depth of the tree should be kept as small as practical so that we don't end up with the random hierarchy like the current phobos and Java (ie - fewer decisions for class writers means fewer mistakes). The key is that the tree we have still needs to be useful and flexible. I see Object and Exception have enough exception-friendly features except for stack traces and perhaps other unknown features. If stack traces ever get introduced to D we could wedge in another branch of the tree but personally I'd prefer to do it though an interface implemented by Exception and (for argument's sake I'll assume my proposal) AssertionFailure (OutOfMemory makes me nervous wrt stack traces for reasons I posted in another thread: where does the memory for the stack trace come from?). That would keep the tree depth down while adding flexibility. Other features could be added to Exception and/or through interfaces.
Ok. Makes sense. (Man, I need to get my paranoia gland sorted!! <g>)
 ps - what does IME mean?
In my estimation.
Apr 13 2005
prev sibling next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 13 Apr 2005 22:33:19 -0400, Ben Hinkle <ben.hinkle gmail.com>  
wrote:

<snip>

Looks good.

My first thought is that "SystemError" is the only one with "Error" in  
it's name. I think it's the most accurate description of what it is but it  
seemed odd that it was the only one. Thoughts?

 Questions:
 1. what should the top few lines of the hierarchy look like?
These ones?
 Object
   OutOfMemory
   AssertionFailure (was AssertError:Error)
      NoSwitchDefault (was SwitchError:Error)
they look good to me.
 2. should modules that currently reuse one exception create subclasses?
Example? I have some vague idea of what you mean but I'd prefer to comment on something concrete.
 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
      throw a raw Exception)
My first thought is no, I say that because "Exception" doesn't tell me what went wrong, it just says something went wrong. What is the reason gc throws it? Shouldn't that be the name of the exception it throws?
 4. what is missing?
Nothing I can think of at this time. Regan
Apr 14 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
 2. should modules that currently reuse one exception create subclasses?
Example? I have some vague idea of what you mean but I'd prefer to comment on something concrete.
std.format is one I had in mind. It reuses FormatError (aka FormatException) for all error conditions and I wonder if user code will want to catch and handle particular failures (eg invalid specifier, int overflow, the infamous formatArg, etc). Currently if they want to react differently to those situations the code would have to inspect the message string which is fragile. There are probably other modules with similar generous exception reuse.
 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
      throw a raw Exception)
My first thought is no, I say that because "Exception" doesn't tell me what went wrong, it just says something went wrong. What is the reason gc throws it? Shouldn't that be the name of the exception it throws?
internal/gc/gc.d currently throws Error("incompatible gc versions") in setGCHandle which is used to sync up dynamically loaded libraries. I thought of adding GCException:Exception and GCVersionException:GCException but then that seemed like overkill. One would think the code loading and syncing up a dynamically loaded lib wouldn't want to treat GC errors differently from whatever else that action can throw. I'm still not sure. Another example that I decided in the other direction was the array casting errors in internal/arraycast. That module throws raw Errors and I figured a subclass of a general CastException would be useful to throw in an opCast for a struct or class. So that one I added to the hierarchy.
Apr 14 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 14 Apr 2005 07:59:07 -0400, Ben Hinkle <ben.hinkle gmail.com>  
wrote:
 2. should modules that currently reuse one exception create subclasses?
Example? I have some vague idea of what you mean but I'd prefer to comment on something concrete.
std.format is one I had in mind. It reuses FormatError (aka FormatException) for all error conditions and I wonder if user code will want to catch and handle particular failures
That was my thought also. If you wanted to "catch and handle particular failures" you'd need some way to distinguish them.
 (eg invalid specifier, int overflow, the infamous
 formatArg, etc). Currently if they want to react differently to those
 situations the code would have to inspect the message string which is
 fragile.
So, the question is "Do we need to catch and handle particular failures in this case?" My answer, no idea sorry.
 There are probably other modules with similar generous exception
 reuse.
Indeed. What do you think the pros/cons of subclassing vs throwing <exception_name> with a differing 'cause' are in these sorts of cases?
 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
      throw a raw Exception)
My first thought is no, I say that because "Exception" doesn't tell me what went wrong, it just says something went wrong. What is the reason gc throws it? Shouldn't that be the name of the exception it throws?
internal/gc/gc.d currently throws Error("incompatible gc versions") in setGCHandle which is used to sync up dynamically loaded libraries. I thought of adding GCException:Exception and GCVersionException:GCException but then that seemed like overkill. One would think the code loading and syncing up a dynamically loaded lib wouldn't want to treat GC errors differently from whatever else that action can throw. I'm still not sure.
What other errors can arise? FileNotFound, PermissionDenied, GCVersionException? i.e. might you want to catch FileNotFound and give the user a chance to find the dll for you?
 Another example that I decided in the other direction was the array  
 casting
 errors in internal/arraycast. That module throws raw Errors and I  
 figured a
 subclass of a general CastException would be useful to throw in an opCast
 for a struct or class. So that one I added to the hierarchy.
Makes sense. Regan
Apr 14 2005
prev sibling parent reply "Maxime Larose" <mlarose broadsoft.com> writes:
Comments:
1. Assertion Failure and sub-classes should have stack tracing. Should they
then have a common ancestor with Exceptions? (see my post in other thread).
It would be cleaner if all stack-traced object inherited through the same
base object, but the functionality can be imported by other means.
2. As others have said, I would definitely rename SystemError to
SystemException (deprecating the old name for a while perhaps). It is really
a sore thumb...
3. I would trim on the numbers of exceptions. Examples:

ParamRangeException are needed. Less exceptions means more consistency
overall in D programs. ParamException means the client code screwed up.
Stack trace should tell you where.


Conceptually, I undersand there is a difference. In practice though, it
means you called code that does nothing. I wouldeliminate one of the two.




mean in practice? It tells us *where* the exception occured, not *what*
occured. The exception name should refer to what occured. For instance, if
Zlib failed because a file was not found, a FileOpenException should be
sent.

Honestly, before we reinvent the wheel, I believe we should take a long hard

much as possible. These languages have been in the field for some time and
some thought went into their exceptions hierarchy design. I would leverage
this thought process as much as possible.

The reason I'm saying that is that somehow this hierarchy seems contrived...
It seems to stem from a desire to map what is currently there to something a
little better (which would in itself be a *very* good thing, don't get me
wrong). However, I believe a more in-depth redesign would be more
profitable.

***
Walter, Ben, and all,

Taking a step back, I see in this community people actively participating,
obviously willing to improve the language and make things better. This is
extremely valuable. Why not use these resources and this talent in a more...
productive manner? Maybe I have been away from newgroup for too long, but
all these posts back and forth hardly seem productive to me. What seems to
be going on is endless debates about points of detail, while overall not
much is achieved. Don't get me wrong, debating is good. As long as it leads
somewhere... I have proposed to spend time investigating stack tracing. You
Ben are intend on redesigning the exception hierarchy. I am sure other
people would like to contribute in various other ways.

Why doesn't Walter "elect" some people to make high level design proposals
on chosen topics?  I'm sure that over the years he's come to recognize
individuals who have made a sizeable contribution to D (like you Ben).
The idea would be to channel all our ideas to one person responsible for
drafting a high level design about a specific topic (subject expert). Walter
would later appose his seal (or not) on that document and implementation
could begin, by Walter himself or by a designated individual(s). Walter
would have the last word: if he believes the document does not adequately
covers possible design alternatives and/or that the suggested amendment is
inappropriate, he could veto it (at a political price, of course... ;)

The workload would be shared between Walter and the community and I am sure
we would all reap the benefits quite rapidly. That is how open source
projects work anyway, no? Walter would be the big Kauna and he would have a
few lieutenants working for him. I know I'm not proposing anything new. It
just appears to me that even at this point, Walter probably can't cope with
all the threads, all the suggestions, all the bugs, etc.

Anyway, the bottom line for me I guess is that I'm willing to make a
contribution to D if I can because I believe it has a lot of potential.
However, I have no time to spend in newsgroup debating endlessly. I suppose
it is probably the same for the most interesting elements in this community.
I'm available, use me or lose me!  ;)

No kidding, even writing this, I'm afraid I'm losing my time. What if
Walter's idea is that the exception hierarchy is 100% fine as it is? What
impact do we have? On the other hand, if Walter elected you Ben as subject
expert on this matter, well, I'd spend 5 times as much time as I spent
writing this, making research on my own and proposing amendments a lot more
tangible than "super-class is enough". I'd give alternatives, examples, etc.
to make my point and try to convince you because in the end you would be
writing the official proposal. We all know that consensus is something
unachievable, so there must be one person to receive all comments on a given
subject and weighs alternatives. As it stands, who's responsible for making
a decision? At this stage, the D community lives on hope...

So, Walter, what say you?

Max



"Ben Hinkle" <ben.hinkle gmail.com> wrote in message
news:d3kkph$2t76$1 digitaldaemon.com...
 Over the past few days/weeks I've been going over the phobos exception
 usage. Below is my proposal for modifying the phobos exception class
 inheritance hierarchy (indenting indicates subclassing). I have no idea if
 Walter would actually accept anything close to this proposal, but I figure
 what the heck. See notes and questions at the end, too.

 Object
    OutOfMemory
    AssertionFailure (was AssertError:Error)
       NoSwitchDefault (was SwitchError:Error)
    Exception
       ParamException (new)
          ParamNullException (new)
          ParamRangeException (new)
       IndexException (new)
          ArrayBoundsException (was ArrayBoundsError:Error)
       CollectionCopyException (new)
          ArrayCopyException (was Error in internal/arraycat.d)
       NotSupportedException (new)
       NotImplementedException (new)
       AddressException
       Base64Exception
          Base64CharException
       CastException (new)
          ArrayCastException (was Error in internal/arraycast.d)
       ConvException (was ConvError:Error)
          ConvOverflowException (was ConvOverflowError:ConvError)
       DateParseException (was DateParseError:Error)
       SystemError (see Regan's code posted on thread about std.syserror)
          FileException (was FileException:Exception)
          SocketException (was SocketException:Exception)
             SocketAcceptException
          HostException (was HostException:Exception)
          RegistryException (was RegistryException:Win32Exception)
          ExeModuleException (was ExeModuleException:Exception)
       FormatException (was FormatError:Error)
       ModuleCtorException (was ModuleCtorError:Exception)
       OpenRJException
          DatabaseException
          InvalidKeyException
          InvalidTypeException
       RegExpException (was RegExpError:Error)
       StreamException
          ReadException
          WriteException
          SeekException
          StreamFileException
             OpenException
       StringException
       ThreadException (was ThreadError:Error)
          OutOfThreadsException (new)
       URIException (was URIError:Error)
       UTFException (was UtfError:Error)
       ZipException
       ZlibException

 Notes:
 1. removed std.windows.registry.Win32Exception since it overlaps with
      SystemError for Windows
 2. remove FooError aliases for std.stream exceptions
 3. some exceptions might be thrown with SystemError causes
      (eg StreamFileException, ThreadException)
 4. RegistryException is thrown once without a system error code
 5. NotSupportedException will be a cause in
      - std.mmfile some thrown FileExceptions
      - std.stream in a StreamException that replaces a raw Exception
      - std.zip in several ZipExceptions
 6. Backwards incompatibilities are limited (hopefully) to class names
 involving Error
    and subclassing Error. The subclassing Error switches to Exception
except
    for asserts and switch defaults don't subclass Exception in the new
 scheme.
 7. The array errors now subclass general reusable errors.

 Exception is defined as
 class Exception {
     char[] msg;
     Object cause; // new

     this(char[] msg, Object cause = null) { // new
         this.msg = msg;
         this.cause = cause; // new
     }

     void print() {
         printf("%.*s\n", msg);
         if (cause) cause.print(); // new
     }

     char[] toString() { return msg; }
 }

 For the definition of SystemError see Regan's post
 http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21282

 Questions:
 1. what should the top few lines of the hierarchy look like?
 2. should modules that currently reuse one exception create subclasses?
 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
      throw a raw Exception)
 4. what is missing?
Apr 14 2005
next sibling parent reply "Maxime Larose" <mlarose broadsoft.com> writes:
If I may complement my ealier proposal, it should be obvious that subject
experts should have some kind of real-life industry knowledge and experience
in the field... The last thing we want is having new grads drafting
proposals... (not that I have anything against new grads mind you).

The subjects experts could even be voted on by the community itself (with
prehaps Walter having a veto).

Max


"Maxime Larose" <mlarose broadsoft.com> wrote in message
news:d3lpvn$te3$1 digitaldaemon.com...
 Comments:
 1. Assertion Failure and sub-classes should have stack tracing. Should
they
 then have a common ancestor with Exceptions? (see my post in other
thread).
 It would be cleaner if all stack-traced object inherited through the same
 base object, but the functionality can be imported by other means.
 2. As others have said, I would definitely rename SystemError to
 SystemException (deprecating the old name for a while perhaps). It is
really
 a sore thumb...
 3. I would trim on the numbers of exceptions. Examples:

 ParamRangeException are needed. Less exceptions means more consistency
 overall in D programs. ParamException means the client code screwed up.
 Stack trace should tell you where.


 Conceptually, I undersand there is a difference. In practice though, it
 means you called code that does nothing. I wouldeliminate one of the two.




ZlibException
 mean in practice? It tells us *where* the exception occured, not *what*
 occured. The exception name should refer to what occured. For instance, if
 Zlib failed because a file was not found, a FileOpenException should be
 sent.

 Honestly, before we reinvent the wheel, I believe we should take a long
hard

 much as possible. These languages have been in the field for some time and
 some thought went into their exceptions hierarchy design. I would leverage
 this thought process as much as possible.

 The reason I'm saying that is that somehow this hierarchy seems
contrived...
 It seems to stem from a desire to map what is currently there to something
a
 little better (which would in itself be a *very* good thing, don't get me
 wrong). However, I believe a more in-depth redesign would be more
 profitable.

 ***
 Walter, Ben, and all,

 Taking a step back, I see in this community people actively participating,
 obviously willing to improve the language and make things better. This is
 extremely valuable. Why not use these resources and this talent in a
more...
 productive manner? Maybe I have been away from newgroup for too long, but
 all these posts back and forth hardly seem productive to me. What seems to
 be going on is endless debates about points of detail, while overall not
 much is achieved. Don't get me wrong, debating is good. As long as it
leads
 somewhere... I have proposed to spend time investigating stack tracing.
You
 Ben are intend on redesigning the exception hierarchy. I am sure other
 people would like to contribute in various other ways.

 Why doesn't Walter "elect" some people to make high level design proposals
 on chosen topics?  I'm sure that over the years he's come to recognize
 individuals who have made a sizeable contribution to D (like you Ben).
 The idea would be to channel all our ideas to one person responsible for
 drafting a high level design about a specific topic (subject expert).
Walter
 would later appose his seal (or not) on that document and implementation
 could begin, by Walter himself or by a designated individual(s). Walter
 would have the last word: if he believes the document does not adequately
 covers possible design alternatives and/or that the suggested amendment is
 inappropriate, he could veto it (at a political price, of course... ;)

 The workload would be shared between Walter and the community and I am
sure
 we would all reap the benefits quite rapidly. That is how open source
 projects work anyway, no? Walter would be the big Kauna and he would have
a
 few lieutenants working for him. I know I'm not proposing anything new. It
 just appears to me that even at this point, Walter probably can't cope
with
 all the threads, all the suggestions, all the bugs, etc.

 Anyway, the bottom line for me I guess is that I'm willing to make a
 contribution to D if I can because I believe it has a lot of potential.
 However, I have no time to spend in newsgroup debating endlessly. I
suppose
 it is probably the same for the most interesting elements in this
community.
 I'm available, use me or lose me!  ;)

 No kidding, even writing this, I'm afraid I'm losing my time. What if
 Walter's idea is that the exception hierarchy is 100% fine as it is? What
 impact do we have? On the other hand, if Walter elected you Ben as subject
 expert on this matter, well, I'd spend 5 times as much time as I spent
 writing this, making research on my own and proposing amendments a lot
more
 tangible than "super-class is enough". I'd give alternatives, examples,
etc.
 to make my point and try to convince you because in the end you would be
 writing the official proposal. We all know that consensus is something
 unachievable, so there must be one person to receive all comments on a
given
 subject and weighs alternatives. As it stands, who's responsible for
making
 a decision? At this stage, the D community lives on hope...

 So, Walter, what say you?

 Max



 "Ben Hinkle" <ben.hinkle gmail.com> wrote in message
 news:d3kkph$2t76$1 digitaldaemon.com...
 Over the past few days/weeks I've been going over the phobos exception
 usage. Below is my proposal for modifying the phobos exception class
 inheritance hierarchy (indenting indicates subclassing). I have no idea
if
 Walter would actually accept anything close to this proposal, but I
figure
 what the heck. See notes and questions at the end, too.

 Object
    OutOfMemory
    AssertionFailure (was AssertError:Error)
       NoSwitchDefault (was SwitchError:Error)
    Exception
       ParamException (new)
          ParamNullException (new)
          ParamRangeException (new)
       IndexException (new)
          ArrayBoundsException (was ArrayBoundsError:Error)
       CollectionCopyException (new)
          ArrayCopyException (was Error in internal/arraycat.d)
       NotSupportedException (new)
       NotImplementedException (new)
       AddressException
       Base64Exception
          Base64CharException
       CastException (new)
          ArrayCastException (was Error in internal/arraycast.d)
       ConvException (was ConvError:Error)
          ConvOverflowException (was ConvOverflowError:ConvError)
       DateParseException (was DateParseError:Error)
       SystemError (see Regan's code posted on thread about std.syserror)
          FileException (was FileException:Exception)
          SocketException (was SocketException:Exception)
             SocketAcceptException
          HostException (was HostException:Exception)
          RegistryException (was RegistryException:Win32Exception)
          ExeModuleException (was ExeModuleException:Exception)
       FormatException (was FormatError:Error)
       ModuleCtorException (was ModuleCtorError:Exception)
       OpenRJException
          DatabaseException
          InvalidKeyException
          InvalidTypeException
       RegExpException (was RegExpError:Error)
       StreamException
          ReadException
          WriteException
          SeekException
          StreamFileException
             OpenException
       StringException
       ThreadException (was ThreadError:Error)
          OutOfThreadsException (new)
       URIException (was URIError:Error)
       UTFException (was UtfError:Error)
       ZipException
       ZlibException

 Notes:
 1. removed std.windows.registry.Win32Exception since it overlaps with
      SystemError for Windows
 2. remove FooError aliases for std.stream exceptions
 3. some exceptions might be thrown with SystemError causes
      (eg StreamFileException, ThreadException)
 4. RegistryException is thrown once without a system error code
 5. NotSupportedException will be a cause in
      - std.mmfile some thrown FileExceptions
      - std.stream in a StreamException that replaces a raw Exception
      - std.zip in several ZipExceptions
 6. Backwards incompatibilities are limited (hopefully) to class names
 involving Error
    and subclassing Error. The subclassing Error switches to Exception
except
    for asserts and switch defaults don't subclass Exception in the new
 scheme.
 7. The array errors now subclass general reusable errors.

 Exception is defined as
 class Exception {
     char[] msg;
     Object cause; // new

     this(char[] msg, Object cause = null) { // new
         this.msg = msg;
         this.cause = cause; // new
     }

     void print() {
         printf("%.*s\n", msg);
         if (cause) cause.print(); // new
     }

     char[] toString() { return msg; }
 }

 For the definition of SystemError see Regan's post
 http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/21282

 Questions:
 1. what should the top few lines of the hierarchy look like?
 2. should modules that currently reuse one exception create subclasses?
 3. when is it ok to just throw Exception? (ie - should internal/gc/gc.d
      throw a raw Exception)
 4. what is missing?
Apr 14 2005
next sibling parent "Ben Hinkle" <bhinkle mathworks.com> writes:
"Maxime Larose" <mlarose broadsoft.com> wrote in message 
news:d3lu7o$11bg$1 digitaldaemon.com...
 If I may complement my ealier proposal, it should be obvious that subject
 experts should have some kind of real-life industry knowledge and 
 experience
 in the field... The last thing we want is having new grads drafting
 proposals... (not that I have anything against new grads mind you).

 The subjects experts could even be voted on by the community itself (with
 prehaps Walter having a veto).

 Max
I'm not sure what you are referring to. What new grad and what proposal do you object to?
Apr 14 2005
prev sibling next sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Maxime Larose" <mlarose broadsoft.com> wrote in message 
news:d3lu7o$11bg$1 digitaldaemon.com...
 If I may complement my ealier proposal, it should be obvious that subject
 experts should have some kind of real-life industry knowledge and 
 experience
 in the field... The last thing we want is having new grads drafting
 proposals... (not that I have anything against new grads mind you).

 The subjects experts could even be voted on by the community itself (with
 prehaps Walter having a veto).

 Max
If you were referring to me here are some google search strings for info about my background (google find me back to 1985). "hinkle hackers guide to adam" (made $20K on those books which was good money in high-school). In 85 or so I switched to the mac. I was the primary coder for later releases of MacMath (google for "Cornell MacMath") in the late 80's early 90's. Did non-commercial coding in grad school. Then in 99 went to "real" commercial software houses - but honestly it's the same thing as the commercial stuff I did in the 80's and 90's. Even if you weren't referring to me it was fun for me to surf around through the past and relive those good ol' days. Enjoy the time-warp. :-)
Apr 14 2005
parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
 Then in 99 went to "real" commercial software houses
oops - meant 98.
Apr 14 2005
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <d3lu7o$11bg$1 digitaldaemon.com>, Maxime Larose says...
If I may complement my ealier proposal, it should be obvious that subject
experts should have some kind of real-life industry knowledge and experience
in the field... The last thing we want is having new grads drafting
proposals... (not that I have anything against new grads mind you).
FWIW, I've heard fantastic suggestions from "new grads" and terrible suggestions from seasoned programmers. I would rather evaluate each suggestion on its own merit than filter based on experience.
The subjects experts could even be voted on by the community itself (with
prehaps Walter having a veto).
I don't know how well an official vote would work in this forum, but every topic gets an implicit vote through responses. It's generally pretty easy to tell who likes an idea and who doesn't even without a show of hands. Sean
Apr 14 2005
parent reply "Maxime Larose" <mlarose broadsoft.com> writes:
 from seasoned programmers.  I would rather evaluate each suggestion on its
own
 merit than filter based on experience.
I absolutely agree. I couldn't care less about experience myself. What I was trying to say is that the person writing the official draf should have enough experience to weighs the pros and the cons of each design/architecture approach. Like it or not, the more stuff you have seen, the more you know about what is done in the field (and perhaps more importantly what shouldn't be done). A perspective that newbies lack. How do you know a design is better than another? Often, the poor design looks "fishy" without you really knowing what is wrong with it. By thinking more about it, the problems with the fishy design are exposed. Call it whatever you want (intuition, etc.), in my book that's experience. Granted there are "experienced" people that are experienced at making crap. They wouldn't know a bad design from a good one if you explained it to them a 100 times. I'd take a newbie anytime over these people. I'm *not* suggesting we filter any suggestion based on experience. As you say, let every suggestion stand on its own merit. (And no Ben, I wasn't referring to you! ;) Max "Sean Kelly" <sean f4.ca> wrote in message news:d3m9sq$1e5t$1 digitaldaemon.com...
 In article <d3lu7o$11bg$1 digitaldaemon.com>, Maxime Larose says...
If I may complement my ealier proposal, it should be obvious that subject
experts should have some kind of real-life industry knowledge and
experience
in the field... The last thing we want is having new grads drafting
proposals... (not that I have anything against new grads mind you).
FWIW, I've heard fantastic suggestions from "new grads" and terrible
suggestions
 from seasoned programmers.  I would rather evaluate each suggestion on its
own
 merit than filter based on experience.

The subjects experts could even be voted on by the community itself (with
prehaps Walter having a veto).
I don't know how well an official vote would work in this forum, but every
topic
 gets an implicit vote through responses.  It's generally pretty easy to
tell who
 likes an idea and who doesn't even without a show of hands.


 Sean
Apr 14 2005
parent "Carlos Santander B." <csantander619 gmail.com> writes:
Maxime Larose wrote:
 
 I absolutely agree. I couldn't care less about experience myself. What I was
 trying to say is that the person writing the official draf should have
 enough experience to weighs the pros and the cons of each
 design/architecture approach. Like it or not, the more stuff you have seen,
 the more you know about what is done in the field (and perhaps more
 importantly what shouldn't be done). A perspective that newbies lack. How do
 you know a design is better than another? Often, the poor design looks
 "fishy" without you really knowing what is wrong with it. By thinking more
 about it, the problems with the fishy design are exposed. Call it whatever
 you want (intuition, etc.), in my book that's experience. Granted there are
 "experienced" people that are experienced at making crap. They wouldn't know
 a bad design from a good one if you explained it to them a 100 times. I'd
 take a newbie anytime over these people.
LOL!
 
 I'm *not* suggesting we filter any suggestion based on experience. As you
 say, let every suggestion stand on its own merit.
 
 (And no Ben, I wasn't referring to you! ;)
 
 Max
 
 
-- Carlos Santander Bernal JP2, you'll always live in our minds
Apr 14 2005
prev sibling parent "Ben Hinkle" <bhinkle mathworks.com> writes:
"Maxime Larose" <mlarose broadsoft.com> wrote in message 
news:d3lpvn$te3$1 digitaldaemon.com...
 Comments:
 1. Assertion Failure and sub-classes should have stack tracing. Should 
 they
 then have a common ancestor with Exceptions? (see my post in other 
 thread).
 It would be cleaner if all stack-traced object inherited through the same
 base object, but the functionality can be imported by other means.
Adding a common base class between Object and Exception would be easily added with 100% backwards compatibility once stack traces became possible. Why cross that bridge before we need to? In other words, with the hierarchy I've proposed we leave open the option of how to implement stack tracing. Given that it doesn't exist yet it would be premature to impose any API for it. If I'm mistaken about my assertion that adding a base class later is 100% backwards compatible then I totally agree we need to figure this out now.
 2. As others have said, I would definitely rename SystemError to
 SystemException (deprecating the old name for a while perhaps). It is 
 really
 a sore thumb...
ok - I'm very open to hearing from people. I have no strong opinion either way. So please people speak up.
 3. I would trim on the numbers of exceptions. Examples:

 ParamRangeException are needed. Less exceptions means more consistency
 overall in D programs. ParamException means the client code screwed up.
 Stack trace should tell you where.
As I explained in another thread ParamNull is useful for two reasons: 1) shortens the throw code and makes it more consistent. All I have to type is throw new ParamNullException("var name") instead of throw new ParamException("Parameter can't be null","var name") Since null parameter checks are very common it makes sense to make it easy. 2) allows different exceptions for something being null and something being null but out of the desired range or for some other reason. I could see removing ParamRangeException, though, and having user code just throw a ParamException for those.

sounds reasonable.

 Conceptually, I undersand there is a difference. In practice though, it
 means you called code that does nothing. I wouldeliminate one of the two.
It's a useful distinction I picked up from Java. You throw NotImpl in stuff you haven't gotten to yet but plan to and NotSupported in stuff that the OS or whatever won't ever support.

could be. I just kept what was there before and didn't look into that very closely.

good idea

opCast overloads should be able to throw a similar exception as casting an array IMO. Currently casting an array throws a bare Error so we could just go back to that.

 ZlibException
 mean in practice? It tells us *where* the exception occured, not *what*
 occured. The exception name should refer to what occured. For instance, if
 Zlib failed because a file was not found, a FileOpenException should be
 sent.
That's what the 'cause' is for. It can be used to both chain exceptions as they get caught and thrown up the stack or it can be used to indicate what happened that caused the first exception to be thrown. In my original post I indicated where I think 'cause' should be used but that was a first pass and people who know more about the particular modules should do whatever they think makes sense. To address your particular example of Zlib and file-not-found I can't see any file management in std.zlib so I'm not sure what you are referring to.
 Honestly, before we reinvent the wheel, I believe we should take a long 
 hard

 much as possible. These languages have been in the field for some time and
 some thought went into their exceptions hierarchy design. I would leverage
 this thought process as much as possible.
agreed.
 The reason I'm saying that is that somehow this hierarchy seems 
 contrived...
 It seems to stem from a desire to map what is currently there to something 
 a
 little better (which would in itself be a *very* good thing, don't get me
 wrong). However, I believe a more in-depth redesign would be more
 profitable.
please keep the suggestions coming. My proposal was trying to rearrange and unify the existing exceptions so I could very well believe it didn't go far enough in changing things around. Keep in mind the details of the hierarchy will change as phobos modules move around and change. [snip]
 ***
 Walter, Ben, and all,

 Taking a step back, I see in this community people actively participating,
 obviously willing to improve the language and make things better. This is
 extremely valuable. Why not use these resources and this talent in a 
 more...
 productive manner? Maybe I have been away from newgroup for too long, but
 all these posts back and forth hardly seem productive to me. What seems to
 be going on is endless debates about points of detail, while overall not
 much is achieved. Don't get me wrong, debating is good. As long as it 
 leads
 somewhere... I have proposed to spend time investigating stack tracing. 
 You
 Ben are intend on redesigning the exception hierarchy. I am sure other
 people would like to contribute in various other ways.
I'm confident *something* will happen - the question is exactly what Walter (and the community) is willing to accept. Walter goes with the community on many things (though not all obviously) so as long as we have an open and representative debate I see it as all good stuff. [snip good stuff]
Apr 14 2005