October 23, 2008
On Fri, Oct 24, 2008 at 6:47 AM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Sergey Gromov wrote:
>>
>> Thu, 23 Oct 2008 14:44:46 -0500,
>> Andrei Alexandrescu wrote:
>>>
>>> Sorry, I meant to catch Exception. My point was, if I want to print an informative message, the exception should be able to provide it without having to encode it in its type.
>>
>> It's all nice and simple until you want to localize.  Then all your 'informative compiler-provided messages' appear as garbage to a non- English-speaking user.  They need to be translated somehow.  And the translation is likely to be based upon the context, not upon an arbitrary string exception contains.
>
> No, translation would have to be provided via a string table. And guess who provides the key for that table.

But what Sergey is pointing out is that
1) if you rely on a human readable string for the key, then you have
to fix things when some maintenance programmer fixes a spelling error
in the message
2) if you rely on human readable strings in that are in 3rd party
libraries then you have to find all those strings some how.  Could be
difficult without source.

So if you're going to translate then having an actual key, a unique identifying symbol not meant for human consumption, is a better approach.

--bb
October 24, 2008
Fri, 24 Oct 2008 08:54:49 +0900,
Bill Baxter wrote:
> On Fri, Oct 24, 2008 at 6:47 AM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> > Sergey Gromov wrote:
> >>
> >> Thu, 23 Oct 2008 14:44:46 -0500,
> >> Andrei Alexandrescu wrote:
> >>>
> >>> Sorry, I meant to catch Exception. My point was, if I want to print an informative message, the exception should be able to provide it without having to encode it in its type.
> >>
> >> It's all nice and simple until you want to localize.  Then all your 'informative compiler-provided messages' appear as garbage to a non- English-speaking user.  They need to be translated somehow.  And the translation is likely to be based upon the context, not upon an arbitrary string exception contains.
> >
> > No, translation would have to be provided via a string table. And guess who provides the key for that table.
> 
> But what Sergey is pointing out is that
> 1) if you rely on a human readable string for the key, then you have
> to fix things when some maintenance programmer fixes a spelling error
> in the message
> 2) if you rely on human readable strings in that are in 3rd party
> libraries then you have to find all those strings some how.  Could be
> difficult without source.
> 
> So if you're going to translate then having an actual key, a unique identifying symbol not meant for human consumption, is a better approach.

Correct.  Thank you for putting this together.  But there is even more to it than that: the library exceptions are usually too low-level and too specific to spit at the user as is.  They need to be analysed and converted into a more appropriate form or action.  And exception must provide means for such analysis other than message string parsing.
October 24, 2008
Sean Kelly wrote:
> Perhaps I'm simply getting old... when did memory use become irrelevant?  I grant that making an application exception safe is more difficult if out of memory conditions are considered recoverable, but I don't think it's tremendously more difficult.

I'm currently studying Computer Engineering at university. I don't think a single programming course I've taken has _mentioned_ running out of memory (next quarter I'm taking Operating Systems, so hopefully that will). One class mentioned memory complexity as a side issue, but never got into it. Even at work, I've never been asked to think about it.
October 24, 2008
Andrei Alexandrescu wrote:
> Robert Fraser wrote:
>> Andrei Alexandrescu wrote:
>>> Jarrett Billingsley wrote:
>>>> On Wed, Oct 22, 2008 at 6:49 AM, Jacob Carlborg <doobnet@gmail.com> wrote:
>>>>> I think the name ArrayBoundsException should be changed to a more general
>>>>> name like BoundsException, OutOfBoundsException or
>>>>> IndexOutOfBoundsException. Then you can use the exception in every class
>>>>> that have some sort of index operation and not just for an array/array
>>>>> class.
>>>>>
>>>>
>>>> 2nded.
>>>
>>> I agree. In fact I wanted to ask you all the following question. What do
>>> you think about the current exception hierarchy in phobos? I think it is
>>> terrible. Each module in std you open, the first piece of code to be
>>> seen is the "class ThisModuleNameException" definition. In many (most?)
>>> cases the module-specific exception does absolutely nothing in addition
>>> to its base class. The putative reader (including me) tends to scroll non-critically over that passage without even blinking, mumbling in a trance - of course, yes, each module should define at least one exception type.
>>>
>>> Until one day when you stop scrolling and say, wait a minute. This all is repetition. And there are alternatives to catching by type - you can catch the base type and consult a field. And in fact I don't remember seeing code that depends on exceptions thrown from different modules having different types. There's something wrong here!
>>>
>>> I think most exception classes in phobos should be yanked if it's possible for their functionality (often nil) to be moved in the Exception base class. The module name should be a member. If someone needs to deal with an exception thrown from a specific module, they can always inspect the field. We don't need a huge hierarchy for that.
>>>
>>>
>>> Andrei
>>
>> Yes, you _could_ use a field... but the "catch a subclass" style is already there and is supported by the language, so _why_ use a field? Which of the following is easier?:
>>
>> Option A:
>> ---------
>> try
>> {
>>      new Socket(30587);
>> }
>> catch(SocketException e)
>> {
>>      printf("Could not open socket\n");
>> }
>>
>> Option B:
>> ---------
>> try
>> {
>>     new Socket(30587);
>> }
>> catch(Exception e)
>> {
>>     if(e.type == ExceptionType.Socket)
>>         printf("Could not open socket\n");
>>     else
>>         throw e;
>> }
> 
> I think you'd be hard-pressed to justify the "if" inside the second example. You couldn't create a Socket, period. It doesn't matter where exactly the exception was generated from.
> 
> That's one thing about large exception hierarchies: everybody can come with cute examples on how they could be useful. As soon as the rubber hits the road, however, differentiating exceptions by type becomes useless.
> 
> 
> Andrei

So in most cases you don't need it... But why throw it out for the cases in which you do (or make it harder to use). In other words, is there any _harm_ being done by having a large exception hierarchy?
October 24, 2008
Andrei Alexandrescu wrote:
>             r.tellFailed( e.toString );

Now that's just wrong. toString should be used for internal debugging purposes. If there's a recoverable error and you want to show it to the user, in a big product, it will need to be internationalized. The worry about what language to display the string in should not be given to the exception thrower, it should be given to the catcher.
October 24, 2008
Sergey Gromov wrote:
> Fri, 24 Oct 2008 08:54:49 +0900,
> Bill Baxter wrote:
>> On Fri, Oct 24, 2008 at 6:47 AM, Andrei Alexandrescu
>> <SeeWebsiteForEmail@erdani.org> wrote:
>>> Sergey Gromov wrote:
>>>> Thu, 23 Oct 2008 14:44:46 -0500,
>>>> Andrei Alexandrescu wrote:
>>>>> Sorry, I meant to catch Exception. My point was, if I want to print an
>>>>> informative message, the exception should be able to provide it without
>>>>> having to encode it in its type.
>>>> It's all nice and simple until you want to localize.  Then all your
>>>> 'informative compiler-provided messages' appear as garbage to a non-
>>>> English-speaking user.  They need to be translated somehow.  And the
>>>> translation is likely to be based upon the context, not upon an arbitrary
>>>> string exception contains.
>>> No, translation would have to be provided via a string table. And guess who
>>> provides the key for that table.
>> But what Sergey is pointing out is that
>> 1) if you rely on a human readable string for the key, then you have
>> to fix things when some maintenance programmer fixes a spelling error
>> in the message
>> 2) if you rely on human readable strings in that are in 3rd party
>> libraries then you have to find all those strings some how.  Could be
>> difficult without source.
>>
>> So if you're going to translate then having an actual key, a unique
>> identifying symbol not meant for human consumption, is a better
>> approach.
> 
> Correct.  Thank you for putting this together.  But there is even more to it than that: the library exceptions are usually too low-level and too specific to spit at the user as is.  They need to be analysed and converted into a more appropriate form or action.  And exception must provide means for such analysis other than message string parsing.

Right -- and what action the program was taking to cause the exception also must be taken into account.
October 24, 2008
On Fri, Oct 24, 2008 at 10:42 AM, Robert Fraser <fraserofthenight@gmail.com> wrote:
> Sean Kelly wrote:
>>
>> Perhaps I'm simply getting old... when did memory use become irrelevant?
>>  I grant that making an application exception safe is more difficult if out
>> of memory conditions are considered recoverable, but I don't think it's
>> tremendously more difficult.
>
> I'm currently studying Computer Engineering at university. I don't think a single programming course I've taken has _mentioned_ running out of memory (next quarter I'm taking Operating Systems, so hopefully that will). One class mentioned memory complexity as a side issue, but never got into it. Even at work, I've never been asked to think about it.

People do still develop for embedded devices with small memory and/or
no virtual memory.
I'm pretty sure it's still a serious concern if you live in that world.

--bb
October 24, 2008
Bill Baxter wrote:
> On Fri, Oct 24, 2008 at 10:42 AM, Robert Fraser
> <fraserofthenight@gmail.com> wrote:
>> Sean Kelly wrote:
>>> Perhaps I'm simply getting old... when did memory use become irrelevant?
>>>  I grant that making an application exception safe is more difficult if out
>>> of memory conditions are considered recoverable, but I don't think it's
>>> tremendously more difficult.
>> I'm currently studying Computer Engineering at university. I don't think a
>> single programming course I've taken has _mentioned_ running out of memory
>> (next quarter I'm taking Operating Systems, so hopefully that will). One
>> class mentioned memory complexity as a side issue, but never got into it.
>> Even at work, I've never been asked to think about it.
> 
> People do still develop for embedded devices with small memory and/or
> no virtual memory.
> I'm pretty sure it's still a serious concern if you live in that world.
> 
> --bb

I'm not saying it doesn't come up in practice; I'm saying developers are trained not to think about it in most cases. And programming to handle a small amount of memory is a different problem than programming to gracefully fail when the program runs out of memory (for example, my program might only use 10k of RAM... but if that 10k isn't there, it might just crash with an error message).

The problem with an OutOfMemoryError being treated as an Exception is that if there are many catch(Exception) blocks, an out-of-memory error will propagate logic bugs across the program (since no one is cleaning up the memory, most allocations will fail). So instead of a nice, clean error, the suer will experience weird and frustrating behavior that doesn't mention memory at all.
October 25, 2008
On Fri, 24 Oct 2008 16:04:53 -0700, Robert Fraser wrote:

> Bill Baxter wrote:
>> On Fri, Oct 24, 2008 at 10:42 AM, Robert Fraser <fraserofthenight@gmail.com> wrote:
>>> Sean Kelly wrote:
>>>> Perhaps I'm simply getting old... when did memory use become
>>>> irrelevant?
>>>>  I grant that making an application exception safe is more difficult
>>>>  if out
>>>> of memory conditions are considered recoverable, but I don't think
>>>> it's tremendously more difficult.
>>> I'm currently studying Computer Engineering at university. I don't think a single programming course I've taken has _mentioned_ running out of memory (next quarter I'm taking Operating Systems, so hopefully that will). One class mentioned memory complexity as a side issue, but never got into it. Even at work, I've never been asked to think about it.
>> 
>> People do still develop for embedded devices with small memory and/or
>> no virtual memory.
>> I'm pretty sure it's still a serious concern if you live in that world.
>> 
>> --bb
> 
> I'm not saying it doesn't come up in practice; I'm saying developers are trained not to think about it in most cases. And programming to handle a small amount of memory is a different problem than programming to gracefully fail when the program runs out of memory (for example, my program might only use 10k of RAM... but if that 10k isn't there, it might just crash with an error message).
> 
> The problem with an OutOfMemoryError being treated as an Exception is that if there are many catch(Exception) blocks, an out-of-memory error will propagate logic bugs across the program (since no one is cleaning up the memory, most allocations will fail). So instead of a nice, clean error, the suer will experience weird and frustrating behavior that doesn't mention memory at all.

The problem with it being an error is that the programmer has no way to catch and remain usable, leaving the user blissfully unaware he needs to buy more ram. If there are many catch(Exception)'s around, the programmer needs to rethink what he is doing when creating a stable program.

D doesn't force a try or throw of exceptions for this very reason; people usually use the catch(Exception) because they don't know what needs to be caught and don't care but are forced to catch it, not because their program is crashing from an exception (well, that is what I do).
October 25, 2008
KennyTM~ wrote:
> Robert Fraser wrote:
>> Sean Kelly wrote:
>>> Denis Koroskin wrote:
>>>> On Wed, 22 Oct 2008 16:22:02 +0400, Jarrett Billingsley <jarrett.billingsley@gmail.com> wrote:
>>>>
>>>>> On Wed, Oct 22, 2008 at 6:49 AM, Jacob Carlborg <doobnet@gmail.com> wrote:
>>>>>> I think the name ArrayBoundsException should be changed to a more general
>>>>>> name like BoundsException, OutOfBoundsException or
>>>>>> IndexOutOfBoundsException. Then you can use the exception in every class
>>>>>> that have some sort of index operation and not just for an array/array
>>>>>> class.
>>>>>>
>>>>>
>>>>> 2nded.
>>>>
>>>> Agreed. BTW, why it is not an Error but Exception?
>>>
>>> The Error class was created shortly before release and I didn't get around to reclassifying the exceptions in druntime.  From memory though, I think that OutOfMemoryException and UtfException should remain as-is, but the remaining exceptions should probably be errors.  Any objections?
>>>
>>> And as for ArrayBoundsException... how about IndexOutOfBoundsError. It's long, but probably the most self-explanatory.  Also, any value in retaining ArrayBoundsError and having it subclass this?  I'd think not, but figured I'd ask anyway.
>>>
>>>
>>> Sean
>>
>> Ah NOOOOO! Please don't make an out of memory catchable with a plain catch(Exception) .... In most programs... pretty much every non-trivial desktop application I can think of... an out-of memory state is basically unrecoverable. In the few cases it would need to be, there would need to be significant handling code, and that would have to be at the right location in the program (i.e. when first opening a file), not in the closest catch-all block some intern down the hallway may have thrown in.
>>
>> Out of memory is an Error subclass in Java and C#, so there's precedent there. catch(Exception) shouldn't be used - but it is, quite often, so things that would cause issues that a user could not normally be expected to recover from should be Error subclasses.
>>
>> Indexing I could see being an exception since that's deterministic and the user's fault. So I guess I disagree on both counts ;-P. Although since index errors don't appear in release modes in D, that gives more case for it to be an Error.
> 
> Make OutOfMemoryException the own subclass of Throwable? Then we have
> 
> Throwable
>   Exception
>   Error
>   OutOfMemoryException
> 
> or we maybe we can have (jokingly)
> 
> Throwable
>   Exception    // Recoverable
>   Error        // Should not be recoverable
>   ChallengingException  // Recoverable but I won't touch it.
>     OutOfMemoryException // Let programmer to force GC to release memory
>     CPUOnFireException   // Let programmer to call local fire station through modem.
>     // etc...
> 

Even though the last suggestion was partially meant as a joke, I think it is actually a good idea. One could have a third hierarchy of exception classes, for exceptions like OutOfMemoryException that one should be able to catch, but that shouldn't be caught by default along with other exceptions. Sort of a "middle ground" between Exception and Error.

Not sure about the name "ChallengingException", though. ;) How about SpecialException, CriticalException or something like that?

-Lars