October 05, 2014
On Sunday, 5 October 2014 at 20:46:16 UTC, Walter Bright wrote:
> On 10/5/2014 3:00 AM, Tobias Müller wrote:
>> All the bad buildings from the ancient romans already came down while the
>> last 2000 years. The best 1% survived.
>
> Yay for survivorship bias!

The same happens when asking people if such or such dictatorship was good or bad. You hear "it wasn't so bad, after all". Yes, because they only ask the survivors, they don't go to ask the dead, too.

Sorry, my rant about politics.
October 05, 2014
On 10/5/2014 2:55 PM, eles wrote:
> The same happens when asking people if such or such dictatorship was good or
> bad. You hear "it wasn't so bad, after all". Yes, because they only ask the
> survivors, they don't go to ask the dead, too.

Yeah, I've often wondered what the dead soldiers would say about wars - whether it was worth it or not. Only the ones who lived get interviewed.

> Sorry, my rant about politics.

October 05, 2014
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".


> Right now Throwable/Error docs heavily suggest catching it is "shoot yourself in
> the foot" thing and new compiler release can possibly change its behaviour
> without notice. I'd like to have a bit more specific documentation about what
> can and what can't be expected. Experimental observations are that one shouldn't
> rely on any cleanup code (RAII / scope(exit)) to happen but other than that it
> is OK to consume Error if execution context for it (fiber in our case) gets
> terminated. As D1 compiler does not change it is good enough observation for
> practical means. But for D2 it would be nice to have some official clarification.

Definitely unwinding may or may not happen from Error throws, "nothrow" functions may throw Errors, and optimizers need not account for Errors being thrown.

Attempting to unwind the stack when an Error is thrown may cause further corruption (if the Error was thrown because of corruption), another reason for the language not to try to do it.

An Error is, by definition, unrecoverable.


> 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.

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.

October 05, 2014
On Sunday, 5 October 2014 at 23:01:48 UTC, Walter Bright wrote:
>
> Definitely unwinding may or may not happen from Error throws, "nothrow" functions may throw Errors, and optimizers need not account for Errors being thrown.

This is the real concern.  If an Error is thrown out of a nothrow function that contains a synchronized block, for example, the mutex might still be locked.  So the only viable option is to terminate, even for something theoretically recoverable like a divide by zero or an OOME.
October 06, 2014
On 10/5/2014 4:28 PM, Sean Kelly wrote:
> On Sunday, 5 October 2014 at 23:01:48 UTC, Walter Bright wrote:
>>
>> Definitely unwinding may or may not happen from Error throws, "nothrow"
>> functions may throw Errors, and optimizers need not account for Errors being
>> thrown.
>
> This is the real concern.  If an Error is thrown out of a nothrow function that
> contains a synchronized block, for example, the mutex might still be locked.  So
> the only viable option is to terminate, even for something theoretically
> recoverable like a divide by zero or an OOME.

Divide by zero is not recoverable since you don't know why it occurred. It could be the result of overflowing a buffer with 0s. Until a human debugs it and figures out why it happened, it not recoverable.

Because it could be the result of corruption like buffer overflows, the less code that is executed between the detection of the bug and terminating the program, the safer the program is. Continuing execution may mess up user data, may execute injected malware, etc.

October 06, 2014
On 10/5/14, 2:27 PM, Walter Bright wrote:
> On 10/5/2014 9:18 AM, Andrei Alexandrescu wrote:
>> Exceptions are all about centralized error handling. How, and how
>> often, would
>> you handle FileNotFoundException differently than
>> PermissionDeniedException?
>
> You would handle it differently if there was extra data attached to that
> particular exception, specific to that sort of error.

Indeed. Very few in Phobos do. -- Andrei

October 06, 2014
On 05/10/14 18:18, Andrei Alexandrescu wrote:

> Exceptions are all about centralized error handling. How, and how often,
> would you handle FileNotFoundException differently than
> PermissionDeniedException?

Probably not that often. But I don't think it's up to "File" to decide that. I think "File" should throw a specific error as possible containing all details it has. Then it's up to the user of "File" how to handle the exception. If you're not interested in the differences between FileNotFoundException and PermissionDeniedException, then catch the base class instead.

The details provided between these two exception could be different as well. FileNotFoundException should contain the path of the file that wasn't found. PermissionDeniedException should contain some information about if it was the source or target that caused the exception to be thrown. Think of a copy or move operation.

How would one localize error messages if the specific exception is not known?

-- 
/Jacob Carlborg
October 06, 2014
On 05/10/14 23:50, Dmitry Olshansky wrote:

> Seems like it should be possible to define multiple interfaces for
> exceptions, and then catch by that (and/or combinations of such).
>
> Each of interface would be interested in a particular property of
> exception. Then catching by:
>
> FileException with PermissionException
>
> would mean OS-level permission viloated and it was during file access,
>
> while
>
> ProcessException with PermissionException would mean process
> manipulation was forbiden, etc.
>
> Of course, some code may be interested only in PermissionException side
> of things, while other code may want to contain anything related to
> files, and the catch-all-sensible-ones inside of the main function.

Why not just define two different PermissionException?

-- 
/Jacob Carlborg
October 06, 2014
06-Oct-2014 10:33, Jacob Carlborg пишет:
> On 05/10/14 23:50, Dmitry Olshansky wrote:
>
>> Seems like it should be possible to define multiple interfaces for
>> exceptions, and then catch by that (and/or combinations of such).
>>
>> Each of interface would be interested in a particular property of
>> exception. Then catching by:
>>
>> FileException with PermissionException
>>
>> would mean OS-level permission viloated and it was during file access,
>>
>> while
>>
>> ProcessException with PermissionException would mean process
>> manipulation was forbiden, etc.
>>
>> Of course, some code may be interested only in PermissionException side
>> of things, while other code may want to contain anything related to
>> files, and the catch-all-sensible-ones inside of the main function.
>
> Why not just define two different PermissionException?

Rather N permission exceptions. It gets worse with more problem domains to cover. Again the trick is being able to catch all PermissionExceptions, including for exception type you may not know in advance.

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.

-- 
Dmitry Olshansky
October 06, 2014
On 10/5/14, 11:31 PM, Jacob Carlborg wrote:
> On 05/10/14 18:18, Andrei Alexandrescu wrote:
>
>> Exceptions are all about centralized error handling. How, and how often,
>> would you handle FileNotFoundException differently than
>> PermissionDeniedException?
>
> Probably not that often. But I don't think it's up to "File" to decide
> that. I think "File" should throw a specific error as possible
> containing all details it has.

Sure, but that can be distinguished by payload, not type.

> Then it's up to the user of "File" how to
> handle the exception. If you're not interested in the differences
> between FileNotFoundException and PermissionDeniedException, then catch
> the base class instead.
>
> The details provided between these two exception could be different as
> well. FileNotFoundException should contain the path of the file that
> wasn't found. PermissionDeniedException should contain some information
> about if it was the source or target that caused the exception to be
> thrown. Think of a copy or move operation.
>
> How would one localize error messages if the specific exception is not
> known?

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.

Andrei