October 06, 2014
On 10/5/14, 11:39 PM, Dmitry Olshansky wrote:
>
> It's obvious to me that one hierarchy is way to limiting for exceptions,
> simply because there could be many ways to categorize the same set of
> error conditions.

Well put. -- Andrei
October 06, 2014
On Mon, Oct 06, 2014 at 06:46:31AM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
> On 10/5/14, 11:39 PM, Dmitry Olshansky wrote:
> >
> >It's obvious to me that one hierarchy is way to limiting for exceptions, simply because there could be many ways to categorize the same set of error conditions.
> 
> Well put. -- Andrei

What's the alternative, though? I can't think of any solution that
(1) isn't far more complicated than the current state of things and
(2) is easier to use.


T

-- 
"Holy war is an oxymoron." -- Lazarus Long
October 06, 2014
On 06/10/14 15:45, Andrei Alexandrescu wrote:

> Knowledge doesn't have to be by type; just place data inside the
> exception. About the only place where multiple "catch" statements are
> used to make fine distinctions between exception types is in sample code
> showing how to use multiple "catch" statements :o). This whole notion
> that different exceptions need different types is as far as I can tell a
> red herring.

What do you suggest, error codes? I consider that an ugly hack.

-- 
/Jacob Carlborg
October 06, 2014
On 10/6/14, 7:01 AM, H. S. Teoh via Digitalmars-d wrote:
> On Mon, Oct 06, 2014 at 06:46:31AM -0700, Andrei Alexandrescu via Digitalmars-d wrote:
>> On 10/5/14, 11:39 PM, Dmitry Olshansky wrote:
>>>
>>> It's obvious to me that one hierarchy is way to limiting for
>>> exceptions, simply because there could be many ways to categorize the
>>> same set of error conditions.
>>
>> Well put. -- Andrei
>
> What's the alternative, though? I can't think of any solution that
> (1) isn't far more complicated than the current state of things and
> (2) is easier to use.

I'm thinking a simple key-value store Variant[string] would accommodate any state needed for differentiating among exception kinds whenever that's necessary.

It's commonly accepted that the usability scope of OOP has gotten significantly narrower since its heydays. However, surprisingly, the larger community hasn't gotten to the point to scrutinize object-oriented error handling, which as far as I can tell has never delivered.


Andrei

October 06, 2014
On 10/6/14, 7:48 AM, Jacob Carlborg wrote:
> On 06/10/14 15:45, Andrei Alexandrescu wrote:
>
>> Knowledge doesn't have to be by type; just place data inside the
>> exception. About the only place where multiple "catch" statements are
>> used to make fine distinctions between exception types is in sample code
>> showing how to use multiple "catch" statements :o). This whole notion
>> that different exceptions need different types is as far as I can tell a
>> red herring.
>
> What do you suggest, error codes? I consider that an ugly hack.

I don't. On the contrary, I do consider proliferating types to the multiplicity of possible errors an obvious design sin. -- Andrei


October 06, 2014
On Mon, 06 Oct 2014 15:48:31 +0100, Jacob Carlborg <doob@me.com> wrote:

> On 06/10/14 15:45, Andrei Alexandrescu wrote:
>
>> Knowledge doesn't have to be by type; just place data inside the
>> exception. About the only place where multiple "catch" statements are
>> used to make fine distinctions between exception types is in sample code
>> showing how to use multiple "catch" statements :o). This whole notion
>> that different exceptions need different types is as far as I can tell a
>> red herring.
>
> What do you suggest, error codes? I consider that an ugly hack.

Why?

It gives us the benefits of error code return values:
 - ability to easily/cheaply check for/compare them using "switch" on code value (vs comparing/casting types)
 - ability to pass through OS level codes directly

Without any of the penalties:
 - checking for them after every call.
 - losing the return value "slot" or having to engineer multiple return values in the language.
 - having to mix error codes in with valid return values (for int() functions).

We also get:
 - no type proliferation.
 - no arguments about what exception types are needed, or the hierarchy to put them in.

Seems like a win to me.


Of course.. it would be nicer still if there was a list of OS/platform agnostic error codes which were used throughout phobos and could be re-used by client code.  And.. (for example) it would be nice if there was a FileNotFound(string path) function which returned an Exception using the correct code allowing:
  throw FileNotFound(path);

and so on.


I do not know a lot about how exceptions are thrown and caught at the compiler/compiled code level, but perhaps there is even a performance benefit to be had if you know that only 2 possible types (Exception and Error) can/will be thrown..

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
October 06, 2014
On Sunday, 5 October 2014 at 23:01:48 UTC, Walter Bright wrote:
> On 10/5/2014 2:51 PM, Dicebot wrote:
>> On Sunday, 5 October 2014 at 20:41:44 UTC, Walter Bright wrote:
>>> On 10/5/2014 8:35 AM, Dicebot wrote:
>>>> I am fine with non-default being hard but I
>>>> want it to be still possible within legal language restricions.
>>>
>>> D being a systems language, you can without much difficulty do whatever works
>>> for you.
>>
>> Yes but it shouldn't be in undefined behaviour domain. In other words there
>> needs to be a confidence that some new compiler optimization will not break the
>> application completely.
>
> Relying on program state after entering an unknown state is undefined by definition. I don't see how a language can make a statement like "it's probably ok".

It is only in undefined state because language handles Errors that way. At the point of throwing the Error state was perfectly defined and 100% recoverable. This is the typical case for assertion failure in contract - it detects some program flaw like inability to handle specific data combination from other process but it does not mean memory is corrupted or program is inherently broken. Just killing the fiber and continuing with other requests (which don't trigger that unexpected code path) is absolutely fine unless compiler kicks in and optimizes something away in surprising fashion.

If destructors are ignored those must be always ignored and defined in spec. Same for scope(exit) or any similar affected feature. Currently it may or may not attempt cleanup and that is the problem when trying to circumvent the semantics.

>> I think this is the only important concern I have as long as power user stuff
>> remains possible without re-implementing whole exception system from scratch.
>
> You can catch an Error. But what is done from there is up to you - and to do more than just log the error, engage the backup, and exit, I cannot recommend.

Killing whole process is unacceptable in many cases, it will effectively shut down the whole service if faulty request happens at least one in a few seconds.

> To do more, use an Exception. But to throw an Exception when a logic bug has been detected, then try and continue based on it "probably" being ok, is something I cannot recommend and D certainly cannot guarantee anything. If the program does anything that matters, that is.

Assertions / contracts use Error. Do you think it is a better approach to prohibit using `assert` and throw custom exceptions from contracts?
October 06, 2014
On 2014-10-06 17:07, Andrei Alexandrescu wrote:

> I don't. On the contrary, I do consider proliferating types to the
> multiplicity of possible errors an obvious design sin. -- Andrei

You loose the ability to have exception specific data. And no, I don't want to see an associative array of Variants, that's even worse hack then error codes. You'll run in to problems with unique keys and will most likely need to "scope" all keys.

-- 
/Jacob Carlborg
October 06, 2014
On 2014-10-06 18:03, Regan Heath wrote:

> Why?
>
> It gives us the benefits of error code return values:
>   - ability to easily/cheaply check for/compare them using "switch" on
> code value (vs comparing/casting types)
>   - ability to pass through OS level codes directly
>
> Without any of the penalties:
>   - checking for them after every call.
>   - losing the return value "slot" or having to engineer multiple return
> values in the language.
>   - having to mix error codes in with valid return values (for int()
> functions).
>
> We also get:
>   - no type proliferation.
>   - no arguments about what exception types are needed, or the hierarchy
> to put them in.
>
> Seems like a win to me.

Then you'll always catch all exceptions. If error code doesn't match you need to rethrow the exception. Or make a language change that allows to catch based on the error code.

-- 
/Jacob Carlborg
October 06, 2014
Jacob Carlborg <doob@me.com> wrote:
> On 2014-10-06 17:07, Andrei Alexandrescu wrote:
> 
>> I don't. On the contrary, I do consider proliferating types to the multiplicity of possible errors an obvious design sin. -- Andrei
> 
> You loose the ability to have exception specific data. And no, I don't want to see an associative array of Variants, that's even worse hack then error codes. You'll run in to problems with unique keys and will most likely need to "scope" all keys.

Then scope them.