View mode: basic / threaded / horizontal-split · Log in · Help
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
Sean Kelly wrote:
> Jarrett Billingsley wrote:
>> On Wed, Oct 22, 2008 at 7:13 PM, Sean Kelly <sean@invisibleduck.org> 
>> wrote:
>>> Errors represent situations which are typically non-recoverable--program
>>> logic errors, for example, or situations where data corruption may have
>>> occurred--while Exceptions represent the bulk of normal execution 
>>> errors,
>>> including OutOfMemory conditions.
>>
>> How, pray tell, is an app supposed to recover from an out-of-memory 
>> condition?
> 
> By releasing dynamically allocated memory.  I'd expect some to be 
> released automatically as the stack is unrolled to the catch point 
> anyway.  For example:
> 
> void main()
> {
>     try { fn(); }
>     catch( Exception e ) {}
>     int[] x = new int[16384];
> }
> 
> void fn()
> {
>     int[] x = new int[16384];
>     fn();
> }
> 
> Eventually this app will run out of memory (hopefully before it runs out 
> of stack space) and an OutOfMemoryException will be thrown.  As the 
> stack is unwound, all valid references to this memory will be released. 
>  So the allocation in main() should trigger a collection which frees up 
> all the now-unreferenced memory, thus allowing the allocation in main() 
> to succeed.
> 
> For manual recovery, consider an app that does a great deal of internal 
> caching.  On an OutOfMemory condition the app could clear its caches and 
>  then retry the operation.  This is probably a bad example, but I think 
> the general idea of trapping and recovering from such a state is 
> potentially valid.
> 
> 
> Sean

Didn't see this discussion before I went off my tirade. I agree it's 
recoverable and in a perfect world this would be so, but look through 
any large codebase for how many catch(Exception) blocks there are. I'll 
bet you that NONE of the general catch(Exception) blocks (except the 
ones that print an error and exit the program) expect to see, or are 
prepared for, an out of memory exception.

Asking programmers to think about out of memory errors is too much. 
We're trained to assume computers have infinite memory and when they run 
out, the system/runtime is supposed to do drastic things like crashing 
our programs - not start introducing strange logic errors all over the 
place because programmers didn't realize their catch(Exception) blocks 
had to deal with more than "file doesn't exist"
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
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;
}
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
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...
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
Wed, 22 Oct 2008 19:18:57 -0400,
Jarrett Billingsley wrote:
> On Wed, Oct 22, 2008 at 7:13 PM, Sean Kelly <sean@invisibleduck.org> wrote:
> > Errors represent situations which are typically non-recoverable--program
> > logic errors, for example, or situations where data corruption may have
> > occurred--while Exceptions represent the bulk of normal execution errors,
> > including OutOfMemory conditions.
> 
> How, pray tell, is an app supposed to recover from an out-of-memory condition?

In an image editor, a user asks to create a huge image (50k x 50k).  You 
try, run out of memory, and gracefully tell the user that the image was 
too big and you didn't succeed.
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
Wed, 22 Oct 2008 12:01:36 -0700,
Sean Kelly wrote:
> 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.

Maybe IndexingError ?  There are not necessarily any bounds when you're 
indexing into an arbitrary collection.
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
On Thu, 23 Oct 2008 04:02:22 +0400, Sean Kelly <sean@invisibleduck.org>  
wrote:

> Jarrett Billingsley wrote:
>> On Wed, Oct 22, 2008 at 7:13 PM, Sean Kelly <sean@invisibleduck.org>  
>> wrote:
>>> Errors represent situations which are typically  
>>> non-recoverable--program
>>> logic errors, for example, or situations where data corruption may have
>>> occurred--while Exceptions represent the bulk of normal execution  
>>> errors,
>>> including OutOfMemory conditions.
>>  How, pray tell, is an app supposed to recover from an out-of-memory  
>> condition?
>
> By releasing dynamically allocated memory.  I'd expect some to be  
> released automatically as the stack is unrolled to the catch point  
> anyway.  For example:
>
> void main()
> {
>      try { fn(); }
>      catch( Exception e ) {}
>      int[] x = new int[16384];
> }
>
> void fn()
> {
>      int[] x = new int[16384];
>      fn();
> }
>
> Eventually this app will run out of memory (hopefully before it runs out  
> of stack space) and an OutOfMemoryException will be thrown.  As the  
> stack is unwound, all valid references to this memory will be released.  
>   So the allocation in main() should trigger a collection which frees up  
> all the now-unreferenced memory, thus allowing the allocation in main()  
> to succeed.
>
> For manual recovery, consider an app that does a great deal of internal  
> caching.  On an OutOfMemory condition the app could clear its caches and  
>   then retry the operation.  This is probably a bad example, but I think  
> the general idea of trapping and recovering from such a state is  
> potentially valid.
>
>
> Sean

I think that OutOfMemoryException should *not* be recoverable. Instead,  
language should provide some hookable callback (like onOutOfMemoryError())  
which is called when memory limit is reached so that program may free some  
unused memory (which is held by user since it is not garbage-collected)  
and tries to allocate the memory again without failure (return true from  
callback). User might decide to re-throw some other kind of *exception*,  
like NotEnoughMemoryException(), to catch and recover, or pass it (return  
false from callback) which in turn will finally throw OutOfMemoryError().
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
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
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
Sergey Gromov wrote:
> Wed, 22 Oct 2008 19:18:57 -0400,
> Jarrett Billingsley wrote:
>> On Wed, Oct 22, 2008 at 7:13 PM, Sean Kelly <sean@invisibleduck.org> wrote:
>>> Errors represent situations which are typically non-recoverable--program
>>> logic errors, for example, or situations where data corruption may have
>>> occurred--while Exceptions represent the bulk of normal execution errors,
>>> including OutOfMemory conditions.
>> How, pray tell, is an app supposed to recover from an out-of-memory condition?
> 
> In an image editor, a user asks to create a huge image (50k x 50k).  You 
> try, run out of memory, and gracefully tell the user that the image was 
> too big and you didn't succeed.

I could extract many instances of this pattern from my programs. 
Unfortunately, current bugs in the compiler, phobos, or both lead to 
sudden death of the application under certain circumstances. I hope one 
day I'll get around to investigating that.

Andrei
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
Sergey Gromov wrote:
> Wed, 22 Oct 2008 12:01:36 -0700,
> Sean Kelly wrote:
>> 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.
> 
> Maybe IndexingError ?  There are not necessarily any bounds when you're 
> indexing into an arbitrary collection.

STL has range_error. I like that because it's rather general.

Andrei
October 23, 2008
Re: Change the name of ArrayBoundsException in druntime
Denis Koroskin wrote:
> On Thu, 23 Oct 2008 04:02:22 +0400, Sean Kelly <sean@invisibleduck.org> 
> wrote:
> 
>> Jarrett Billingsley wrote:
>>> On Wed, Oct 22, 2008 at 7:13 PM, Sean Kelly <sean@invisibleduck.org> 
>>> wrote:
>>>> Errors represent situations which are typically 
>>>> non-recoverable--program
>>>> logic errors, for example, or situations where data corruption may have
>>>> occurred--while Exceptions represent the bulk of normal execution 
>>>> errors,
>>>> including OutOfMemory conditions.
>>>  How, pray tell, is an app supposed to recover from an out-of-memory 
>>> condition?
>>
>> By releasing dynamically allocated memory.  I'd expect some to be 
>> released automatically as the stack is unrolled to the catch point 
>> anyway.  For example:
>>
>> void main()
>> {
>>      try { fn(); }
>>      catch( Exception e ) {}
>>      int[] x = new int[16384];
>> }
>>
>> void fn()
>> {
>>      int[] x = new int[16384];
>>      fn();
>> }
>>
>> Eventually this app will run out of memory (hopefully before it runs 
>> out of stack space) and an OutOfMemoryException will be thrown.  As 
>> the stack is unwound, all valid references to this memory will be 
>> released.   So the allocation in main() should trigger a collection 
>> which frees up all the now-unreferenced memory, thus allowing the 
>> allocation in main() to succeed.
>>
>> For manual recovery, consider an app that does a great deal of 
>> internal caching.  On an OutOfMemory condition the app could clear its 
>> caches and   then retry the operation.  This is probably a bad 
>> example, but I think the general idea of trapping and recovering from 
>> such a state is potentially valid.
>>
>>
>> Sean
> 
> I think that OutOfMemoryException should *not* be recoverable. Instead, 
> language should provide some hookable callback (like 
> onOutOfMemoryError()) which is called when memory limit is reached so 
> that program may free some unused memory (which is held by user since it 
> is not garbage-collected) and tries to allocate the memory again without 
> failure (return true from callback). User might decide to re-throw some 
> other kind of *exception*, like NotEnoughMemoryException(), to catch and 
> recover, or pass it (return false from callback) which in turn will 
> finally throw OutOfMemoryError().

But one of the best things possible to do is unwind the stack and fall 
back to a higher position with less state. A function cannot do that, an 
exception can. Why do you guys want to avoid exceptions in one of the 
few cases when they are exactly, but exactly what the doctor prescribed?

Andrei
1 2 3 4 5 6 7
Top | Discussion index | About this forum | D home