February 19, 2012
Le 19/02/2012 13:32, Jonathan M Davis a écrit :
> On Sunday, February 19, 2012 13:20:19 deadalnix wrote:
>> Why is the executable size such a big issue ?
>
> Some people complain bitterly about any additional size to the executable at
> all, whether they use all of the symbols in it or not, and if they don't use
> all of the symbols, then they're that much more annoyed by the additional
> size. It crops of semi-frequently around here that someone complains about how
> big hello world is. Most of the problem goes away if phobos because a shared
> library like it's going to eventually, but someone is always going to be
> complaining about binary size - especially with a systems language.
>
> - Jonathan M Davis

I know that people complain. But most of them are unable to explain why it is a problem.

Plus, hello world size is a very stupid exemple accroding to me. It is just like comparaing sorting algorithms with an array of 5 elements. The code bloat that Exception would add is in O(1). So it will get irrevealant in every non trivial program toy like hello world.

Note that Hello World in Java is about 50Mb. It is because the stdlib is big. And it has much more played in favor of java than against. Plus, we consider adding perfect GC (or at least on heap), which would be O(n) on the code bloat. This may be not noticeable on an hello world program, but this will sure generate more code bloat on any real application.
February 19, 2012
On 19/02/2012 01:54, Jonathan M Davis wrote:
> On Sunday, February 19, 2012 01:43:27 Ben Davis wrote:
>> - distinguish between 'bug' exceptions (e.g. null) and 'you're more
>> likely to want to catch this' exceptions (e.g. IO). Maybe the bug ones
>> should have been Errors, since people *usually* don't catch those (and
>> are certainly never required to). As it stands, Errors are reserved for
>> corrupt class files and other VM panic scenarios.
>
> Well, in D, you'd use exceptions derived from Error (though null pointers
> still result in a good ol' segfault). Java's situation is marred by the whole
> thing with checked exceptions. D's basic is better in that regard, I think.
> It's the lack of a proper exception hierarchy where we're worse.

Indeed, I'd noticed I was getting RangeErrors, not RangeExceptions :)

>> - make sure the 'lazy' approach is a good one: the less you type, the
>> fewer exceptions you catch, and the less likely you are to silence those
>> exceptions at runtime. Probably the main problem with the exception
>> hierarchy is that the short names tend to be the more general ones that
>> are more dangerous to catch indiscriminately.
>
> You mean, make the standard exception names really long and ugly, and the more
> specific ones short? e.g. Exception becomes something like
> StandardExceptionThatYouReallyShouldBeCatchingCatchTheDerivedType whereas
> specific exceptions are more like SpecifcEx (though that's a bit extreme)?
>
> Well, while that's a good sentiment, the very nature of more specific
> exceptions means that their namesj are likely to be more specific and therefore
> longer (especially when you have descriptive names). So, I'm not sure that
> that's ultimately all that reasonable, even if the basic idea is a good one.

LOL - yeah, there's a reason I didn't propose any actual names. It's not an easy problem to solve. But I felt the psychology angle might not have been covered and was worth mentioning all the same.

You could name the class "AllExceptions" though.

But as the insidious ones like off-by-ones are Errors (or segfaults), it's definitely a much smaller problem in D than in Java.
February 19, 2012
On 2012-02-19 01:09, Andrei Alexandrescu wrote:
> On 2/18/12 6:03 PM, Jonathan M Davis wrote:
>> On Saturday, February 18, 2012 17:30:10 Andrei Alexandrescu wrote:
>>> The alternative is with virtuals. Do you see a lot of virtuals in base
>>> exceptions? Do you see dramatically different interface for different
>>> exception types?
>>
>> You mean virtual functions? The problem is that each exception type
>> could have
>> information specific to _it_ which makes no sense in a base class. For
>> instance, Exception does to have errno in it. FileException does.
>>
>> If we have GetOptException, it should have a variable for which flag
>> failed.
>> Exception doesn't have that. And what if the flag failed because it
>> was given a
>> bad argument? Then the exception needs a field for that argument. Then
>> you can
>> get something like
>>
>> try
>> getopt(args, ...)
>> catch(MissingArgumentException mae)
>> {
>> stderr.writefln("%s is missing an argument", mae.flag);
>> return -1;
>> }
>> catch(InvalidArgumentException iae)
>> {
>> stderr.writelfln("%s is not a valid argument for %s. You must give it a
>> %s.", mae.arg, mae.flag, mae.expectedType);
>> return -1;
>> }
>> catch(UnknownFlagException ufe)
>> {
>> stderr.writefln("%s is not a known flag.", ufe.ufe);
>> return -1;
>> }
>> catch(GetOptException goe)
>> {
>> stderr.writefln("There was an error with %s", goe.flag);
>> return -1;
>> }
>> //A delegate that you passed to getopt threw an exception.
>> catch(YourException ye)
>> {
>> //...
>> }
>> catch(Exception e)
>> {
>> stderr.writeln("An unexpected error occured.");
>> return -1;
>> }
>>
>> You can't do _anything_ like that right now.
>
> Of course I can. They call it toString(). The code above pretty much
> proves my point with so much wonderful irony.
>
> Andrei
>

If you actually want to try and recover from the error rather than just simply print the error message, toString is out of the window.

-- 
/Jacob Carlborg
February 19, 2012
On 2012-02-19 01:09, Andrei Alexandrescu wrote:
> On 2/18/12 6:03 PM, Jonathan M Davis wrote:
>> On Saturday, February 18, 2012 17:30:10 Andrei Alexandrescu wrote:
>>> The alternative is with virtuals. Do you see a lot of virtuals in base
>>> exceptions? Do you see dramatically different interface for different
>>> exception types?
>>
>> You mean virtual functions? The problem is that each exception type
>> could have
>> information specific to _it_ which makes no sense in a base class. For
>> instance, Exception does to have errno in it. FileException does.
>>
>> If we have GetOptException, it should have a variable for which flag
>> failed.
>> Exception doesn't have that. And what if the flag failed because it
>> was given a
>> bad argument? Then the exception needs a field for that argument. Then
>> you can
>> get something like
>>
>> try
>> getopt(args, ...)
>> catch(MissingArgumentException mae)
>> {
>> stderr.writefln("%s is missing an argument", mae.flag);
>> return -1;
>> }
>> catch(InvalidArgumentException iae)
>> {
>> stderr.writelfln("%s is not a valid argument for %s. You must give it a
>> %s.", mae.arg, mae.flag, mae.expectedType);
>> return -1;
>> }
>> catch(UnknownFlagException ufe)
>> {
>> stderr.writefln("%s is not a known flag.", ufe.ufe);
>> return -1;
>> }
>> catch(GetOptException goe)
>> {
>> stderr.writefln("There was an error with %s", goe.flag);
>> return -1;
>> }
>> //A delegate that you passed to getopt threw an exception.
>> catch(YourException ye)
>> {
>> //...
>> }
>> catch(Exception e)
>> {
>> stderr.writeln("An unexpected error occured.");
>> return -1;
>> }
>>
>> You can't do _anything_ like that right now.
>
> Of course I can. They call it toString(). The code above pretty much
> proves my point with so much wonderful irony.
>
> Andrei
>

Say you want to do something like what Git does:

$ git statu
git: 'statu' is not a git command. See 'git --help'.

Did you mean this?
	status
$

That would be quite hard with just toString.

-- 
/Jacob Carlborg
February 19, 2012
On 02/19/2012 09:26 AM, H. S. Teoh wrote:
> On Sat, Feb 18, 2012 at 11:52:00PM -0800, Jonathan M Davis wrote:
> [...]
>> So, while at first glance, it seems like a good idea, I think that it
>> has too many issues as-is to work. It might be possible to adjust the
>> idea to make it workable though. Right now, it's possible to do it via
>> mixins or calling a function inside the catch, but doing something
>> similar to this would certainly be nice, assuming that we could sort
>> out the kinks.
> [...]
>
> I have an idea. What about "signature constraints" for catch, ala
> template signature constraints? Something like this:
>
> 	try {
> 		...
> 	} catch(IOException e)
> 		if (e.errno in subsetYouWantToHandle)
> 	{
> 		...
> 	}
>
> Just using IOException as an example. The idea is to allow arbitrary
> expressions in the constraint so whatever doesn't satisfy the constraint
> will be regarded as "not caught", even if the base type matches.
>
>
> T
>

Nice.
February 19, 2012
On 02/18/2012 07:52 PM, Andrei Alexandrescu wrote:
> There's a discussion that started in a pull request:
>
> https://github.com/alexrp/phobos/commit/4b87dcf39efeb4ddafe8fe99a0ef9a529c0dcaca
>
>
> Let's come up with a good doctrine for exception defining and handling
> in Phobos. From experience I humbly submit that catching by type is most
> of the time useless.
>
>
> Andrei

Would giving std.concurrency.OwnerTerminated and std.concurrency.LinkTerminated a common supertype make sense?
February 19, 2012
I uploaded my little 2003 article on exception categorization to github,
where I detailed my whole point_of_view_of_the_catch and whole_program_invariant phylosophy for organizing clasess, and compared
C++, .NET and Java hierarchies. Its not a professional article, and I never wrote a translation to english:

https://github.com/jmcabo/ExceptionArticle/blob/master/articuloExcepciones_v2.pdf

--jm


On Sunday, 19 February 2012 at 10:30:45 UTC, Juan Manuel Cabo wrote:
> Hello D community! This is my first post!! I hope I can bring clarity to all this. If not, I apologize.
>
> Some time ago I researched the best way to classify exceptions and build a hierarchy. I came up with the following rules:
>
>
> 1) At the top level, there would be RecoverableExceptions and FatalExceptions (or you can call them something like CatcheableException and FatalExceptions, or Exception and Error).
>
> 2) Fatal exceptions shouldn't be catched. They imply that the program lost basic guarantees to go on (memory corruption, missing essential file, etc.). You could catch them if you wanted to, but it makes no sense other than at your top-level method (main(), etc.).
>
> 3) A RecoverableException can be converted to a FatalException by rethrowing it, once a catch decides so. You shouldn't do the reverse: a FatalException never should be converted to a RecoverableException.
>
> 4) It makes no sense to subclass FatalExceptions since there won't be a catch that groups them in a base type (since they are not catcheable).
>
> 5) Only create a new RecoverableException class type if it makes sense to write a catch for it alone. Otherwise, use an preexisting type.
>
> 6) Only group RecoverableExceptions in a category if it makes sense to write a catch for that category. Please don't group them because its fancy or "cleaner", that is a bad reason.
>
>
> Who decides when an Exception is Unrecoverable? Library code almost never decides it, since an exception is only unrecoverable if the whole_program_invariant got broken, and libraries are only a part of a program. So they will tend to throw RecoverableExceptions, which can be reconverted to Unrecoverable by the program.
>
> In some cases, it is clear that an exception is Unrecoverable. When you call a function without satisfying its arguments precondition (ie: null argument) the only way to fix that is by editing the program. You shouldn't have called it like that in the first place, why would you? So you let the UnrecoverableException bubble up to your main function, and log its stacktrace to fix it.
>
> Unrecoverable means the program got 'tainted', basic guarantees got broken (possible memory corruption, etc.). Most exceptions will be Recoverable.
>
> Now, expanding on the hierarchy: I said that it makes no sense to subclass UnrecoverableExceptions. Recoverable exceptions on the other hand, need to be subclassed _with_the_catch_on_your_mind_. You are passing info from the throw site to the catch site. The catch block is the interpreter of the info, the observer. You are communicating something to the catch block.
>
> So please, do not create a new types if there is no value in writing a catch that only cathes that exception and that can recover from that exception. Otherwise, use an existing type.
>
>
> I wrote these rules some time ago. Please excuse me if they come off a bit pedantic!!!!!!!!!!!! Its all only a clarifying convention.
>
>
> According to all this:
>
> * FileNotFoundException is useful. It tells you what happened. It is a RecoverableException (under my convention) because until it reaches the program, the library doesn't know if the program can recover from that (it could be a system missing file, or just a document the user asked for).
>
> * DiskFailureException is only useful if someone can write a catch for it. If so, then it is a RecoverableException. Only the program can decide if it broke basic guarantees.
>
> * Most argument exceptions are Unrecoverable. A function throwing shouldn't have been called like that in the first place. The only fix is to go back to editing the program. (precondition broken).
>
>
> Another thing: you cannot decide whether an exception is Unrecoverable based only on whether the thing that got broken is the postcondition of a function. It is the whole_program_invariant that decides that. For instance:  findStuff(someStuff)  might not know if someStuff is important enough for the stability of the program if not found. The postcondition is broken if it doesn't return the Stuff. That might be recoverable.
>
> And PLEASE: don't make classifications by the point of view of the cause of the problem. DO make classifications by the point of view of the fixing/recovery of the problem; the catch block is who you are talking to. FileNotFoundBecauseFilesystemUnmounted is worthless.
>
> So, to sum up: (1) it makes no sense to subclass fatal exceptions, and (2) never subclass a RecoverableException if you are not helping a catch block with that (but please do if it aids recovery).
>
> ..so verbose and pedantic for my first post... yikes.. i beg forgiveness!!!
>
>
>
>
> On Sunday, 19 February 2012 at 09:27:48 UTC, Jonathan M Davis wrote:
>> On Sunday, February 19, 2012 19:00:20 Daniel Murphy wrote:
>>> I wasn't really serious about implicit fallthrough.
>>
>> Lately, it seems like I can never tell whether anyone's being serious or not online. :)
>>
>>> Out of the syntaxes I could come up with:
>>> catch(Ex1, Ex2 e)
>>> catch(e : Ex1, Ex2)
>>> catch(Ex1 | Ex2 e) // java 7 syntax, horrible
>>> 
>>> I like (e : list) the best.  Naturally it would also accept a type tuple of
>>> exceptions.
>>> 
>>> http://d.puremagic.com/issues/show_bug.cgi?id=7540
>>
>> LOL. Personally, I actually think that the Java 7 syntax looks great (I'd never seen it before), but catch(e : Ex1, Ex2) is just as good and more consistent with the language as a whole, since it doesn't try to give any operators a new meaning (as Java's does).
>>
>> - Jonathan M Davis


February 19, 2012
On 2/19/12 5:22 AM, deadalnix wrote:
> Le 19/02/2012 08:05, Andrei Alexandrescu a écrit :
>> How about a system in which you can say whether an exception is I/O
>> related, network related, recoverable or not, should be displayed to the
>> user or not, etc. Such is difficult to represent with inheritance alone.
>>
>
> That may sound great on the paper, but it isn't. The fact that an
> exception is recoverable or not depend often on your program and not on
> the cause of the exception.

This is self-evident. Again, the meaning of "recoverable" is "operation may succeed if retried with the same input". It's a hint for the catch code. Of course the program is free to ignore that aspect, retry a number of times, log, display user feedback, and so on. But as far as definition goes the notion is cut and dried.

Andrei

February 19, 2012
On 2/19/12 6:27 AM, Juan Manuel Cabo wrote:
> How about adding a string[string] or a variant[string] to the Exception
> class, so one can know details about the subclassed exception without
> downcasting?

That is a must for custom formatting and i18n.

Andrei


February 19, 2012
On 2/19/12 6:35 AM, deadalnix wrote:
> Le 19/02/2012 09:02, Andrei Alexandrescu a écrit :
>>>> I'm thinking an error is transient if retrying the operation with the
>>>> same exact data may succeed. That's a definition that's simple,
>>>> useful, and easy to operate with.
>>> [...]
>>>
>>> But if that's the case, what's the use of an exception at all?
>>
>> Centralization.
>>
>> Andrei
>>
>
> Please stop answering like that. From the begining of this topic
> Jonathan M Davis, H. S. Teah (and myself ?) raised very valid points.
> What do you expect from that discussion if yourself you do not put any
> arguement on the table ?

The answer is meaningful. The purpose of exceptions is allowing for centralized error handling, and a capabilities-based system makes that simple (e.g. you get to make decisions about recoverability in one place, regardless of which part of the exception hierarchy the exception originated.

Andrei