View mode: basic / threaded / horizontal-split · Log in · Help
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
>> OutOfMemory is practically unrecoverable, but should not be 
>> classed
>> as an unrecoverable exception.
>
> Agreed, in part, why "class" it as anything but what it is?
>
>> Conversely, AssertionFailure is practically recoverable, but most
>> certainly should be classed as unrecoverable.
>
> As above, why "class" it as anything but what it is?

Because there has to be a common type that's catchable, and I don't 
think Object is the appropriate choice.

>> (And the language
>> should mandate and enforce the irrecoverability.)
>
> Disagree.

For reasons so blindingly obvious/insightful that you needn't 
specify them, I guess.
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
On Tue, 12 Apr 2005 16:23:06 +1000, Matthew  
<admin@stlsoft.dot.dot.dot.dot.org> wrote:
>>> OutOfMemory is practically unrecoverable, but should not be
>>> classed
>>> as an unrecoverable exception.
>>
>> Agreed, in part, why "class" it as anything but what it is?
>>
>>> Conversely, AssertionFailure is practically recoverable, but most
>>> certainly should be classed as unrecoverable.
>>
>> As above, why "class" it as anything but what it is?
>
> Because there has to be a common type that's catchable, and I don't
> think Object is the appropriate choice.

So.. you want:

Catchable
  Recoverable
    OutOfMemory
  NonRecoverable
    AssertionFailure

?

>>> (And the language
>>> should mandate and enforce the irrecoverability.)
>>
>> Disagree.
>
> For reasons so blindingly obvious/insightful that you needn't
> specify them, I guess.

Sarcasm is the lowest form of wit.

Why do you need to force a program to terminate? If the programmer wants  
to continue and can do so, they will, if not, they wont. I see no need to  
enforce it.

Regan
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
Matthew wrote:
>>>OutOfMemory is practically unrecoverable, but should not be 
>>>classed
>>>as an unrecoverable exception.
>>
>>Agreed, in part, why "class" it as anything but what it is?
>>
>>
>>>Conversely, AssertionFailure is practically recoverable, but most
>>>certainly should be classed as unrecoverable.
>>
>>As above, why "class" it as anything but what it is?
> 
> 
> Because there has to be a common type that's catchable, and I don't 
> think Object is the appropriate choice.
> 
> 
>>>(And the language
>>>should mandate and enforce the irrecoverability.)
>>
>>Disagree.
> 
> 
> For reasons so blindingly obvious/insightful that you needn't 
> specify them, I guess.

IMO mandating this, that, and the other thing isn't necessarily the 
D-style. If someone for whatever crazy (and/or genius) reason wants to 
try to recover from what would usually be considered irrecoverable 
error, why does the compiler need to stop them?

Here's a possibly insane example. I'm trying to imagine a situation 
where it might be useful to try to make an irrevoverable error 
recoverable. Let's say you're using someone else's library (no source 
provided except headers). The library's pretty useful in some respects, 
but it has some stupid assert that don't make any sense and halts the 
program. Well, if the compiler won't let you try to recover after the 
assert then you might have to give up (it was a long shot anyways). 
Sure, it's not "proper programming practice" to subvert the library 
author's asserts, but sometimes "it kind of works" is all you need. D 
should be the kind of language that allows creativity.

-- 
jcc7
http://jcc_7.tripod.com/d/
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
"Regan Heath" <regan@netwin.co.nz> wrote in message 
news:opso3x5rhn23k2f5@nrage.netwin.co.nz...
> On Tue, 12 Apr 2005 16:23:06 +1000, Matthew 
> <admin@stlsoft.dot.dot.dot.dot.org> wrote:
>>>> OutOfMemory is practically unrecoverable, but should not be
>>>> classed
>>>> as an unrecoverable exception.
>>>
>>> Agreed, in part, why "class" it as anything but what it is?
>>>
>>>> Conversely, AssertionFailure is practically recoverable, but 
>>>> most
>>>> certainly should be classed as unrecoverable.
>>>
>>> As above, why "class" it as anything but what it is?
>>
>> Because there has to be a common type that's catchable, and I 
>> don't
>> think Object is the appropriate choice.
>
> So.. you want:
>
> Catchable
>   Recoverable
>     OutOfMemory
>   NonRecoverable
>     AssertionFailure

You've changed the names of things - Catchable<=>Throwable, 
NonRecoverable <=> Unrecoverable <=> Irrecoverable - which is 
perfectly fine. I'm not allied to them.

You're close to what I'm thinking. Using your terms

Catchable
  Recoverable
     FileNotFoundException
  NonRecoverable
    AssertionFailure

But, as I said in a previous post, I think the jury's still out on 
OutOfMemory. I've a strong suspicion it should fall out as being an 
exception, but I think there's some mileage in discussing whether it 
might have another 'type', e.g. ResourceExhaustion. Reason being 
that, though memory exhaustion is in principle recoverable, in 
practice it is not recoverable (since getting memory to throw/handle 
is tricky, and may require workarounds) and also often so unlikely 
as to make it not worth worrying about.

So, the conversation I'm interesting in seeing is whether these 
characteristics of OutOfMemory are shared by any other resource 
exhaustion. If so, it might be worth our while to do something 
different. After all, a file not being present can be a 'normal' 
(from a user's perspective) runtime condition, whereas memory 
exhaustion is likely to be seen otherwise, even though both are, in 
principle, recoverable.

One that comes to mind is threading keys and/or slots. Whether Win32 
TLS or PTHREADS TSD, inability to allocate a TSS key, or aquire a 
slot for an allocated key, is a pretty terminal condition. More so, 
than running out memory, in fact, although the shutdown might be 
more graceful.

So, I see the taxonomy as being either (now using my/Ben's names):

Object <= not throwable, btw
   Throwable
       Error <= Unrecoverable exceptions
           ContractViolation
           Assertion
       Exception
           FileNotFoundException
           XMLParseException
       Exhaustion
           MemoryExhaustion
           TSSKeyExhaustion

or, if we just lump exhaustions in with exceptions

Object <= not throwable, btw
   Throwable
       Error <= Unrecoverable exceptions
           ContractViolation
           Assertion
       Exception
           FileNotFoundException
           XMLParseException
           MemoryExhaustionException
           TSSKeyExhaustionException


>>>> (And the language
>>>> should mandate and enforce the irrecoverability.)
>>>
>>> Disagree.
>>
>> For reasons so blindingly obvious/insightful that you needn't
>> specify them, I guess.
>
> Sarcasm is the lowest form of wit.

Maybe so, but unstubstantiated opinion is worth precisely nothing. 
It's an inconsiderate waste of other people's time.

> Why do you need to force a program to terminate? If the programmer 
> wants  to continue and can do so, they will, if not, they wont. I 
> see no need to  enforce it.

There are several flaws suggested in your understanding of the issue 
by just those two sentences.


First, "Why do you need to force a program to terminate?". This 
one's simple: The program must be forced to terminate because it has 
violated its design. (Let me digress for a moment and confess that 
before I made the leap into CP-grok-ville this never seemed simple, 
or at least never cut and dried.)

What's at issue here is not that the program has encountered a 
runtime error, or even (the very poorly termed) "unexpected 
situation". What a contract violation states is _precisely_ and 
_absolutely_ that a program has violated its design. An example from 
my recent work was that one of the server components, which served 
as an intermediate between three other components, should never have 
data in its input queues when not in a fully connected state. That 
is the expression of the design. (FYI: two of the other components 
with which it communicated were sockets based, whereas the third was 
a message queue.) When we put it into production all was well, until 
one component outside our control (another, much bigger (<g>) 
company was responsible for that) started sending up information 
through the message queue when it shouldn't.

What happened was that our process immediately cacked itself, and 
printed out a nice lot of information about "VIOLATION: downstream 
XYZ queue not empty in state ABC". Thus, this exposed that the 
implementation of the component was violating the design 
assumptions. The result of that immediate failure was an almost 
immediate realisation of the problem - in about 2 minutes, and a 
very rapid fix - about 90mins work, IIRC.

Now consider if the violation had been recoverable, which would 
certainly have been possible, since there was no memory corruption, 
and, indeed, no corruption of any of the internals of the component 
which violated. These systems produce a *lot* of logging output, and 
it's perfectly possible that a non-terminating log entry would have 
been missed. Furthermore, the error would have manifested 
considerably later, after the now out-of-date messages from the 
downstream queue was passed up through our components and out into 
the outside world. Given the fact that several companies were 
frantically involved in updating networking protocols and 
architectures simultaneously, that bug could have lain dormant for 
days, weeks, or even months. That would have cost both customers and 
the client a lot of money, and also cost us some reputation.


Second: "If the programmer wants to continue and can do so, they 
will, if not, they wont". Who's the programmer? Do you mean the 
user? Do you think that the end users of (even a substantial 
proportion of) systems are programmers? That suggests a 
significantly skewed perspective and, I'm afraid to say, implies 
that your experience is of programming for programmers, rather than 
more "commercial" activities. There's nothing wrong with that, to be 
sure, but it can't provide a base of experience suitable for making 
fundamental decisions on language design issues with very wide 
ramifications.


But let's give you the benefit of the doubt, and assume you 
misspoke, and actually meant: "If the [user] wants to continue and 
can do so, they will, if not, they wont". This one's even more 
simple than the first: There often isn't a user, or the user is 
significantly divorced from the error, separated by 
threads/processes/machines/networks. Even when there is a user, I 
suggest it's highly undesirable to leave it to them, highly ignorant 
of the specifics of your program (and, probably, of computers / 
software engineering in general) to have to attempt to handle 
something that's now operating outside the bounds of its design. 
It's analogous to selling someone a car and, when its brakes fail, 
telling them to drive on at their own risk.


Notwithstanding all the foregoing, there's a much more fundamental, 
albeit little recognised, issue. Computers make a strict 
interpretation of what we, the programmers, instruct them to do. Now 
a contract violation, as I've said, is pure and simple a statement 
that your instructions to the computer (or to the compiler, if you 
will) are fundamentally flawed. Since computers do not have 
redundancy, intuition, instincts, sixth-sense, a friend to call, or 
any other "higher order" functioning, there are exactly two things a 
process can do in that circumstance. It can operate in a 
fundamentally flawed manner, or it can stop. THERE ARE NO OTHER 
OPTIONS. And _that_ is the crux of the matter. Unless and until a 
programmer grasps that concept, they can't grok CP. There's no shame 
in not having doing so. I did 10 years of commercial programming, 
much of it very successful, thank you very much, before I saw the 
light (and I could name you some super famous chaps who're still a 
bit wooly on it). But I can absolutely aver that programming using 
strict CP results in faster development time, *far* more robust 
product, and happier clients and developers alike.


Matthew
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
"J C Calvarese" <jcc7@cox.net> wrote in message 
news:d3fspo$1u0j$1@digitaldaemon.com...
> Matthew wrote:
>>>>OutOfMemory is practically unrecoverable, but should not be 
>>>>classed
>>>>as an unrecoverable exception.
>>>
>>>Agreed, in part, why "class" it as anything but what it is?
>>>
>>>
>>>>Conversely, AssertionFailure is practically recoverable, but 
>>>>most
>>>>certainly should be classed as unrecoverable.
>>>
>>>As above, why "class" it as anything but what it is?
>>
>>
>> Because there has to be a common type that's catchable, and I 
>> don't think Object is the appropriate choice.
>>
>>
>>>>(And the language
>>>>should mandate and enforce the irrecoverability.)
>>>
>>>Disagree.
>>
>>
>> For reasons so blindingly obvious/insightful that you needn't 
>> specify them, I guess.
>
> IMO mandating this, that, and the other thing isn't necessarily 
> the D-style. If someone for whatever crazy (and/or genius) reason 
> wants to try to recover from what would usually be considered 
> irrecoverable error, why does the compiler need to stop them?

There are two parts to this:

1. Implicit in your argument is that the "programmer knows best in 
*all* possible circumstances". I can tell you that, as someone who's 
worked for over 10 years, written 1.5 books, and worked on some very 
successful high risk projects, the one thing I'm sure of is that I 
do _not_ know everything, and I do not always know best. I learn 
something new from more experienced people at least once a month. I 
understand that D has come from the C school where freedom of 
expression (both micro and macro) is valued highly, and is also 
attracting Linux types by whom freedom in all its facets is prized 
most high. In fact I share a lot of that instinct and sentiment. But 
the fact of the matter is that there are very good reasons - 
espoused by people loftier than I - for irrecoverability, and no 
reasons for not having it save for some ephemeral notion of 
"freedom".

2. As I've demonstrated with the STLSoft library's unrecoverable 
class, implementing irrecoverability can be done easily and 
effectively in C++ in the form of a library which one may opt to use 
or not use at ones own discretion. If we would do the same in D, 
there'd be some reason for not having it built into the language. 
However, the reason it can work in C++ is that one can (and should) 
throw by value - and catch by reference, of course - and the death 
tractors of exception objects are invoked in a deterministic manner. 
However, in D exceptions are thrown by reference, and their 
destructors are useless. There is, therefore, no mechanism for a 
library solution to irrecoverability in D. Therefore, we need a 
language-based solution.

> Here's a possibly insane example. I'm trying to imagine a 
> situation where it might be useful to try to make an irrevoverable 
> error recoverable. Let's say you're using someone else's library 
> (no source provided except headers). The library's pretty useful 
> in some respects, but it has some stupid assert that don't make 
> any sense and halts the program. Well, if the compiler won't let 
> you try to recover after the assert then you might have to give up 
> (it was a long shot anyways). Sure, it's not "proper programming 
> practice" to subvert the library author's asserts, but sometimes 
> "it kind of works" is all you need. D should be the kind of 
> language that allows creativity.

It's wrongheaded, I'm afraid. If you fire an assert in a library 
then you're using it counter to its design. If (the expression of) 
its design is wrong, i.e. the assert shouldn't be there, then you've 
got even bigger problems, and any use of it you make which is 
counter to its design cannot be characterised to be anything else. 
Two wrongs cannot make a right.

AFAIK - and I've been discussing this subject with friends and 
colleagues in various settings for a long while - there's only one 
scenario where irrecoverability (for CP violations) makes sense: 
Debuggers. I absolutely want D to support debuggers correctly, but I 
don't accept that the real and significant advantages of 
irrecoverability have to be sacrified for that.

Nonetheless, I do have serious doubts that irrecoverability will be 
incorporated into D, since Walter tends to favour "good enough" 
solutions rather than aiming for strict/theoretical best, and 
because the principles and advantages of irrecoverability are not 
yet sufficiently mainstream. It's a pity though, because it'd really 
lift D's head above its peers. (And without it, there'll be another 
area in which C++ will continue to be able to claim supremacy, 
because D cannot support it in library form.)

Cheers

Matthew
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
Not that I disagree, in principle, but there are still cases where you'd 
want to recover from an "unrecoverable" error. Consider an environment 
like Eclipse, which is built totally out of plugins, and there can be 
hundreds of them. What you're saying is that whenever one of those 
faults, the whole system should abort, which is definitely not what I'd 
want it to do.

I mean, when I do something like inspect a value in a debugger, and the 
value is 150MB and the debugger runs out of memory, I don't want it to 
stop, just because it can't show me a var (which can just as easily 
manifest as an assertion error or whatever)...

Enforcing unrecoverability would be a mistake, if you ask me, although I 
totally support an exception hierarchy that would make "unrecoverable" 
errors something people wouldn't try to catch normally.


xs0


Matthew wrote:
> "Regan Heath" <regan@netwin.co.nz> wrote in message 
> news:opso3x5rhn23k2f5@nrage.netwin.co.nz...
> 
>>On Tue, 12 Apr 2005 16:23:06 +1000, Matthew 
>><admin@stlsoft.dot.dot.dot.dot.org> wrote:
>>
>>>>>OutOfMemory is practically unrecoverable, but should not be
>>>>>classed
>>>>>as an unrecoverable exception.
>>>>
>>>>Agreed, in part, why "class" it as anything but what it is?
>>>>
>>>>
>>>>>Conversely, AssertionFailure is practically recoverable, but 
>>>>>most
>>>>>certainly should be classed as unrecoverable.
>>>>
>>>>As above, why "class" it as anything but what it is?
>>>
>>>Because there has to be a common type that's catchable, and I 
>>>don't
>>>think Object is the appropriate choice.
>>
>>So.. you want:
>>
>>Catchable
>>  Recoverable
>>    OutOfMemory
>>  NonRecoverable
>>    AssertionFailure
> 
> 
> You've changed the names of things - Catchable<=>Throwable, 
> NonRecoverable <=> Unrecoverable <=> Irrecoverable - which is 
> perfectly fine. I'm not allied to them.
> 
> You're close to what I'm thinking. Using your terms
> 
>  Catchable
>    Recoverable
>       FileNotFoundException
>    NonRecoverable
>      AssertionFailure
> 
> But, as I said in a previous post, I think the jury's still out on 
> OutOfMemory. I've a strong suspicion it should fall out as being an 
> exception, but I think there's some mileage in discussing whether it 
> might have another 'type', e.g. ResourceExhaustion. Reason being 
> that, though memory exhaustion is in principle recoverable, in 
> practice it is not recoverable (since getting memory to throw/handle 
> is tricky, and may require workarounds) and also often so unlikely 
> as to make it not worth worrying about.
> 
> So, the conversation I'm interesting in seeing is whether these 
> characteristics of OutOfMemory are shared by any other resource 
> exhaustion. If so, it might be worth our while to do something 
> different. After all, a file not being present can be a 'normal' 
> (from a user's perspective) runtime condition, whereas memory 
> exhaustion is likely to be seen otherwise, even though both are, in 
> principle, recoverable.
> 
> One that comes to mind is threading keys and/or slots. Whether Win32 
> TLS or PTHREADS TSD, inability to allocate a TSS key, or aquire a 
> slot for an allocated key, is a pretty terminal condition. More so, 
> than running out memory, in fact, although the shutdown might be 
> more graceful.
> 
> So, I see the taxonomy as being either (now using my/Ben's names):
> 
> Object <= not throwable, btw
>     Throwable
>         Error <= Unrecoverable exceptions
>             ContractViolation
>             Assertion
>         Exception
>             FileNotFoundException
>             XMLParseException
>         Exhaustion
>             MemoryExhaustion
>             TSSKeyExhaustion
> 
> or, if we just lump exhaustions in with exceptions
> 
> Object <= not throwable, btw
>     Throwable
>         Error <= Unrecoverable exceptions
>             ContractViolation
>             Assertion
>         Exception
>             FileNotFoundException
>             XMLParseException
>             MemoryExhaustionException
>             TSSKeyExhaustionException
> 
> 
> 
>>>>>(And the language
>>>>>should mandate and enforce the irrecoverability.)
>>>>
>>>>Disagree.
>>>
>>>For reasons so blindingly obvious/insightful that you needn't
>>>specify them, I guess.
>>
>>Sarcasm is the lowest form of wit.
> 
> 
> Maybe so, but unstubstantiated opinion is worth precisely nothing. 
> It's an inconsiderate waste of other people's time.
> 
> 
>>Why do you need to force a program to terminate? If the programmer 
>>wants  to continue and can do so, they will, if not, they wont. I 
>>see no need to  enforce it.
> 
> 
> There are several flaws suggested in your understanding of the issue 
> by just those two sentences.
> 
> 
> First, "Why do you need to force a program to terminate?". This 
> one's simple: The program must be forced to terminate because it has 
> violated its design. (Let me digress for a moment and confess that 
> before I made the leap into CP-grok-ville this never seemed simple, 
> or at least never cut and dried.)
> 
> What's at issue here is not that the program has encountered a 
> runtime error, or even (the very poorly termed) "unexpected 
> situation". What a contract violation states is _precisely_ and 
> _absolutely_ that a program has violated its design. An example from 
> my recent work was that one of the server components, which served 
> as an intermediate between three other components, should never have 
> data in its input queues when not in a fully connected state. That 
> is the expression of the design. (FYI: two of the other components 
> with which it communicated were sockets based, whereas the third was 
> a message queue.) When we put it into production all was well, until 
> one component outside our control (another, much bigger (<g>) 
> company was responsible for that) started sending up information 
> through the message queue when it shouldn't.
> 
> What happened was that our process immediately cacked itself, and 
> printed out a nice lot of information about "VIOLATION: downstream 
> XYZ queue not empty in state ABC". Thus, this exposed that the 
> implementation of the component was violating the design 
> assumptions. The result of that immediate failure was an almost 
> immediate realisation of the problem - in about 2 minutes, and a 
> very rapid fix - about 90mins work, IIRC.
> 
> Now consider if the violation had been recoverable, which would 
> certainly have been possible, since there was no memory corruption, 
> and, indeed, no corruption of any of the internals of the component 
> which violated. These systems produce a *lot* of logging output, and 
> it's perfectly possible that a non-terminating log entry would have 
> been missed. Furthermore, the error would have manifested 
> considerably later, after the now out-of-date messages from the 
> downstream queue was passed up through our components and out into 
> the outside world. Given the fact that several companies were 
> frantically involved in updating networking protocols and 
> architectures simultaneously, that bug could have lain dormant for 
> days, weeks, or even months. That would have cost both customers and 
> the client a lot of money, and also cost us some reputation.
> 
> 
> Second: "If the programmer wants to continue and can do so, they 
> will, if not, they wont". Who's the programmer? Do you mean the 
> user? Do you think that the end users of (even a substantial 
> proportion of) systems are programmers? That suggests a 
> significantly skewed perspective and, I'm afraid to say, implies 
> that your experience is of programming for programmers, rather than 
> more "commercial" activities. There's nothing wrong with that, to be 
> sure, but it can't provide a base of experience suitable for making 
> fundamental decisions on language design issues with very wide 
> ramifications.
> 
> 
> But let's give you the benefit of the doubt, and assume you 
> misspoke, and actually meant: "If the [user] wants to continue and 
> can do so, they will, if not, they wont". This one's even more 
> simple than the first: There often isn't a user, or the user is 
> significantly divorced from the error, separated by 
> threads/processes/machines/networks. Even when there is a user, I 
> suggest it's highly undesirable to leave it to them, highly ignorant 
> of the specifics of your program (and, probably, of computers / 
> software engineering in general) to have to attempt to handle 
> something that's now operating outside the bounds of its design. 
> It's analogous to selling someone a car and, when its brakes fail, 
> telling them to drive on at their own risk.
> 
> 
> Notwithstanding all the foregoing, there's a much more fundamental, 
> albeit little recognised, issue. Computers make a strict 
> interpretation of what we, the programmers, instruct them to do. Now 
> a contract violation, as I've said, is pure and simple a statement 
> that your instructions to the computer (or to the compiler, if you 
> will) are fundamentally flawed. Since computers do not have 
> redundancy, intuition, instincts, sixth-sense, a friend to call, or 
> any other "higher order" functioning, there are exactly two things a 
> process can do in that circumstance. It can operate in a 
> fundamentally flawed manner, or it can stop. THERE ARE NO OTHER 
> OPTIONS. And _that_ is the crux of the matter. Unless and until a 
> programmer grasps that concept, they can't grok CP. There's no shame 
> in not having doing so. I did 10 years of commercial programming, 
> much of it very successful, thank you very much, before I saw the 
> light (and I could name you some super famous chaps who're still a 
> bit wooly on it). But I can absolutely aver that programming using 
> strict CP results in faster development time, *far* more robust 
> product, and happier clients and developers alike.
> 
> 
> Matthew
> 
> 
>
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
On Tue, 12 Apr 2005 11:52:53 +0200, xs0 <xs0@xs0.com> wrote:
> Not that I disagree, in principle, but there are still cases where you'd  
> want to recover from an "unrecoverable" error. Consider an environment  
> like Eclipse, which is built totally out of plugins, and there can be  
> hundreds of them. What you're saying is that whenever one of those  
> faults, the whole system should abort, which is definitely not what I'd  
> want it to do.
>
> I mean, when I do something like inspect a value in a debugger, and the  
> value is 150MB and the debugger runs out of memory, I don't want it to  
> stop, just because it can't show me a var (which can just as easily  
> manifest as an assertion error or whatever)...
>
> Enforcing unrecoverability would be a mistake, if you ask me, although I  
> totally support an exception hierarchy that would make "unrecoverable"  
> errors something people wouldn't try to catch normally.

My sentiments exactly.

Regan

> Matthew wrote:
>> "Regan Heath" <regan@netwin.co.nz> wrote in message  
>> news:opso3x5rhn23k2f5@nrage.netwin.co.nz...
>>
>>> On Tue, 12 Apr 2005 16:23:06 +1000, Matthew  
>>> <admin@stlsoft.dot.dot.dot.dot.org> wrote:
>>>
>>>>>> OutOfMemory is practically unrecoverable, but should not be
>>>>>> classed
>>>>>> as an unrecoverable exception.
>>>>>
>>>>> Agreed, in part, why "class" it as anything but what it is?
>>>>>
>>>>>
>>>>>> Conversely, AssertionFailure is practically recoverable, but most
>>>>>> certainly should be classed as unrecoverable.
>>>>>
>>>>> As above, why "class" it as anything but what it is?
>>>>
>>>> Because there has to be a common type that's catchable, and I don't
>>>> think Object is the appropriate choice.
>>>
>>> So.. you want:
>>>
>>> Catchable
>>>  Recoverable
>>>    OutOfMemory
>>>  NonRecoverable
>>>    AssertionFailure
>>   You've changed the names of things - Catchable<=>Throwable,  
>> NonRecoverable <=> Unrecoverable <=> Irrecoverable - which is perfectly  
>> fine. I'm not allied to them.
>>  You're close to what I'm thinking. Using your terms
>>   Catchable
>>    Recoverable
>>       FileNotFoundException
>>    NonRecoverable
>>      AssertionFailure
>>  But, as I said in a previous post, I think the jury's still out on  
>> OutOfMemory. I've a strong suspicion it should fall out as being an  
>> exception, but I think there's some mileage in discussing whether it  
>> might have another 'type', e.g. ResourceExhaustion. Reason being that,  
>> though memory exhaustion is in principle recoverable, in practice it is  
>> not recoverable (since getting memory to throw/handle is tricky, and  
>> may require workarounds) and also often so unlikely as to make it not  
>> worth worrying about.
>>  So, the conversation I'm interesting in seeing is whether these  
>> characteristics of OutOfMemory are shared by any other resource  
>> exhaustion. If so, it might be worth our while to do something  
>> different. After all, a file not being present can be a 'normal' (from  
>> a user's perspective) runtime condition, whereas memory exhaustion is  
>> likely to be seen otherwise, even though both are, in principle,  
>> recoverable.
>>  One that comes to mind is threading keys and/or slots. Whether Win32  
>> TLS or PTHREADS TSD, inability to allocate a TSS key, or aquire a slot  
>> for an allocated key, is a pretty terminal condition. More so, than  
>> running out memory, in fact, although the shutdown might be more  
>> graceful.
>>  So, I see the taxonomy as being either (now using my/Ben's names):
>>  Object <= not throwable, btw
>>     Throwable
>>         Error <= Unrecoverable exceptions
>>             ContractViolation
>>             Assertion
>>         Exception
>>             FileNotFoundException
>>             XMLParseException
>>         Exhaustion
>>             MemoryExhaustion
>>             TSSKeyExhaustion
>>  or, if we just lump exhaustions in with exceptions
>>  Object <= not throwable, btw
>>     Throwable
>>         Error <= Unrecoverable exceptions
>>             ContractViolation
>>             Assertion
>>         Exception
>>             FileNotFoundException
>>             XMLParseException
>>             MemoryExhaustionException
>>             TSSKeyExhaustionException
>>
>>>>>> (And the language
>>>>>> should mandate and enforce the irrecoverability.)
>>>>>
>>>>> Disagree.
>>>>
>>>> For reasons so blindingly obvious/insightful that you needn't
>>>> specify them, I guess.
>>>
>>> Sarcasm is the lowest form of wit.
>>   Maybe so, but unstubstantiated opinion is worth precisely nothing.  
>> It's an inconsiderate waste of other people's time.
>>
>>> Why do you need to force a program to terminate? If the programmer  
>>> wants  to continue and can do so, they will, if not, they wont. I see  
>>> no need to  enforce it.
>>   There are several flaws suggested in your understanding of the issue  
>> by just those two sentences.
>>   First, "Why do you need to force a program to terminate?". This one's  
>> simple: The program must be forced to terminate because it has violated  
>> its design. (Let me digress for a moment and confess that before I made  
>> the leap into CP-grok-ville this never seemed simple, or at least never  
>> cut and dried.)
>>  What's at issue here is not that the program has encountered a runtime  
>> error, or even (the very poorly termed) "unexpected situation". What a  
>> contract violation states is _precisely_ and _absolutely_ that a  
>> program has violated its design. An example from my recent work was  
>> that one of the server components, which served as an intermediate  
>> between three other components, should never have data in its input  
>> queues when not in a fully connected state. That is the expression of  
>> the design. (FYI: two of the other components with which it  
>> communicated were sockets based, whereas the third was a message  
>> queue.) When we put it into production all was well, until one  
>> component outside our control (another, much bigger (<g>) company was  
>> responsible for that) started sending up information through the  
>> message queue when it shouldn't.
>>  What happened was that our process immediately cacked itself, and  
>> printed out a nice lot of information about "VIOLATION: downstream XYZ  
>> queue not empty in state ABC". Thus, this exposed that the  
>> implementation of the component was violating the design assumptions.  
>> The result of that immediate failure was an almost immediate  
>> realisation of the problem - in about 2 minutes, and a very rapid fix -  
>> about 90mins work, IIRC.
>>  Now consider if the violation had been recoverable, which would  
>> certainly have been possible, since there was no memory corruption,  
>> and, indeed, no corruption of any of the internals of the component  
>> which violated. These systems produce a *lot* of logging output, and  
>> it's perfectly possible that a non-terminating log entry would have  
>> been missed. Furthermore, the error would have manifested considerably  
>> later, after the now out-of-date messages from the downstream queue was  
>> passed up through our components and out into the outside world. Given  
>> the fact that several companies were frantically involved in updating  
>> networking protocols and architectures simultaneously, that bug could  
>> have lain dormant for days, weeks, or even months. That would have cost  
>> both customers and the client a lot of money, and also cost us some  
>> reputation.
>>   Second: "If the programmer wants to continue and can do so, they  
>> will, if not, they wont". Who's the programmer? Do you mean the user?  
>> Do you think that the end users of (even a substantial proportion of)  
>> systems are programmers? That suggests a significantly skewed  
>> perspective and, I'm afraid to say, implies that your experience is of  
>> programming for programmers, rather than more "commercial" activities.  
>> There's nothing wrong with that, to be sure, but it can't provide a  
>> base of experience suitable for making fundamental decisions on  
>> language design issues with very wide ramifications.
>>   But let's give you the benefit of the doubt, and assume you misspoke,  
>> and actually meant: "If the [user] wants to continue and can do so,  
>> they will, if not, they wont". This one's even more simple than the  
>> first: There often isn't a user, or the user is significantly divorced  
>> from the error, separated by threads/processes/machines/networks. Even  
>> when there is a user, I suggest it's highly undesirable to leave it to  
>> them, highly ignorant of the specifics of your program (and, probably,  
>> of computers / software engineering in general) to have to attempt to  
>> handle something that's now operating outside the bounds of its design.  
>> It's analogous to selling someone a car and, when its brakes fail,  
>> telling them to drive on at their own risk.
>>   Notwithstanding all the foregoing, there's a much more fundamental,  
>> albeit little recognised, issue. Computers make a strict interpretation  
>> of what we, the programmers, instruct them to do. Now a contract  
>> violation, as I've said, is pure and simple a statement that your  
>> instructions to the computer (or to the compiler, if you will) are  
>> fundamentally flawed. Since computers do not have redundancy,  
>> intuition, instincts, sixth-sense, a friend to call, or any other  
>> "higher order" functioning, there are exactly two things a process can  
>> do in that circumstance. It can operate in a fundamentally flawed  
>> manner, or it can stop. THERE ARE NO OTHER OPTIONS. And _that_ is the  
>> crux of the matter. Unless and until a programmer grasps that concept,  
>> they can't grok CP. There's no shame in not having doing so. I did 10  
>> years of commercial programming, much of it very successful, thank you  
>> very much, before I saw the light (and I could name you some super  
>> famous chaps who're still a bit wooly on it). But I can absolutely aver  
>> that programming using strict CP results in faster development time,  
>> *far* more robust product, and happier clients and developers alike.
>>   Matthew
>>
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
On Tue, 12 Apr 2005 18:57:10 +1000, Matthew  
<admin@stlsoft.dot.dot.dot.dot.org> wrote:
> "Regan Heath" <regan@netwin.co.nz> wrote in message
> news:opso3x5rhn23k2f5@nrage.netwin.co.nz...
>> On Tue, 12 Apr 2005 16:23:06 +1000, Matthew
>> <admin@stlsoft.dot.dot.dot.dot.org> wrote:

<snip>

>>> Because there has to be a common type that's catchable, and I
>>> don't
>>> think Object is the appropriate choice.
>>
>> So.. you want:
>>
>> Catchable
>>   Recoverable
>>     OutOfMemory
>>   NonRecoverable
>>     AssertionFailure
>
> You've changed the names of things - Catchable<=>Throwable,
> NonRecoverable <=> Unrecoverable <=> Irrecoverable - which is
> perfectly fine. I'm not allied to them.

I was trying to reflect your statement above about wanting something  
'catchable'.
Food for thought - Catchable (sorta) implies throwable, throwable doesn't  
(necesarily) imply catchable.

<snip>

> though memory exhaustion is in principle recoverable, in
> practice it is not recoverable (since getting memory to throw/handle
> is tricky, and may require workarounds) and also often so unlikely
> as to make it not worth worrying about.

The point Ben made in his original post (to which I agree) is that this is  
a per-application decision, it cannot be made "in general".

> So, the conversation I'm interesting in seeing is whether these
> characteristics of OutOfMemory are shared by any other resource
> exhaustion.

Like running out of operating system handles, file handles, socket  
handles...

<snip>

> So, I see the taxonomy as being either (now using my/Ben's names):
>
> Object <= not throwable, btw
>     Throwable
>         Error <= Unrecoverable exceptions
>             ContractViolation
>             Assertion
>         Exception
>             FileNotFoundException
>             XMLParseException
>         Exhaustion
>             MemoryExhaustion
>             TSSKeyExhaustion
>
> or, if we just lump exhaustions in with exceptions
>
> Object <= not throwable, btw
>     Throwable
>         Error <= Unrecoverable exceptions
>             ContractViolation
>             Assertion
>         Exception
>             FileNotFoundException
>             XMLParseException
>             MemoryExhaustionException
>             TSSKeyExhaustionException

So, in essence you just want to insert "throwable" in between object and  
the rest of the tree.

>> Why do you need to force a program to terminate? If the programmer
>> wants  to continue and can do so, they will, if not, they wont. I
>> see no need to  enforce it.

<snip>

> First, "Why do you need to force a program to terminate?". This
> one's simple: The program must be forced to terminate because it has
> violated its design.

Correction: The program *must* terminate *if* it has violated its design.

Do you know the design of a program someone is going to write in the  
future?

How can you say with utmost surety that under circumstance X that program  
has violated it's design and *must* terminate?

<snip>

> Second: "If the programmer wants to continue and can do so, they
> will, if not, they wont". Who's the programmer? Do you mean the
> user?

No.

<snip>

> But let's give you the benefit of the doubt, and assume you
> misspoke, and actually meant: "If the [user] wants to continue and
> can do so, they will, if not, they wont".

No, I did not mean that.

<snip>

> Notwithstanding all the foregoing, there's a much more fundamental,
> albeit little recognised, issue. Computers make a strict
> interpretation of what we, the programmers, instruct them to do. Now
> a contract violation, as I've said, is pure and simple a statement
> that your instructions to the computer (or to the compiler, if you
> will) are fundamentally flawed.

Correct, and if the program violates it's design it should terminate (in  
the most sensible way possible). However, none of this addresses the issue  
that you cannot know a future programs design nor whether it should  
terminate under any given 'exception'.

So as to clear any confusion, under what circumstance would you enforce  
program termination? in other words, which exception or error would you  
make un-catchable?

Regan
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
>> Maybe we could shorten these ArgumentExceptions to ArgExceptions or
>> ParamException since it's obvious what Arg and Param mean. So how about
>>      ParamException
>>        ParamNullException
>>        ParamRangeException
>>
>
> Just thinking about this, null and out of range are effectively the same 
> thing, as null is "out of range" for a parameter that "cannot be null'. So 
> we *could* just combine them.

The .Net doc explains that Range is for things that are non-null but still 
illegal (or for primitive types out of range). For example if a function 
takes a pointer to an int and the int must not be 5. I think it would be 
handy to have both. A null check is probably 75% of all input checking 
anyway - at least with a project with lots of classes.

> But then, of course, the reason for not combining them is so we can catch 
> them seperately:
>
> void foo(int a){}
>
> try {
>   foo(5);
> } catch(ParamNullException e) {
> } catch(ParamRangeException e) {
> }
>
> Otherwise we could just say:
>
> class ParamException {
>   this(char[] param, char[] problem) {
>   }
> }
>
> And have it print "ParamException: (%s) is %s", eg:
> "ParamException: (a) is out of range"
> "ParamException: (a) is null"
> "ParamException: (a) is not my favourite number"
> "ParamException: (a) is unlucky for some"

If one doesn't care about the distinction between Null and Range then one 
can catch ParamException. It's true the string and printed exception would 
have the more detailed class name.

> <Warning: wacky idea>
> It's a pity the class tree isn't more 'obvious' then we could simply drop 
> the redundant 'Exception' alltogether. eg.
>
> Exception
>   Parameter
>     Null
>     OutOfRange
>
> Is this:
>
> try {
> } catch(OutOfRange e) {
> }
>
> really that opaque that it requires this:
>
> try {
> } catch(ParamRangeException e) {
> }
>
> ?
>
> Of course, it then becomes possible to have collisions within the tree.
>
> Exception
>   Aaaaa
>     Here
>   Bbbbb
>     Here
>
> Exception.Aaaaa.Here
> Exception.Bbbbb.Here
>
> are both called "Here".
> </wacky idea>

This was suggested in the naming thread. It isn't that bad since the Here's 
can be distinguished by package and module names. Now that I think about it 
the Exception was used to indicate that it subclasses Exception, which seems 
useful.

ps - I mistakenly printed out those old threads and now I can symathize with 
Walter's statement that removing "dead quotes" from replies is useful - 
probably 75% or more of the printouts were lazy quoting that added nothing 
to the thread. One printout was 73 pages long.
April 12, 2005
Re: recoverable and unrecoverable errors or exceptions
>> So, I see the taxonomy as being either (now using my/Ben's 
>> names):
>>
>> Object <= not throwable, btw
>>     Throwable
>>         Error <= Unrecoverable exceptions
>>             ContractViolation
>>             Assertion
>>         Exception
>>             FileNotFoundException
>>             XMLParseException
>>         Exhaustion
>>             MemoryExhaustion
>>             TSSKeyExhaustion
>>
>> or, if we just lump exhaustions in with exceptions
>>
>> Object <= not throwable, btw
>>     Throwable
>>         Error <= Unrecoverable exceptions
>>             ContractViolation
>>             Assertion
>>         Exception
>>             FileNotFoundException
>>             XMLParseException
>>             MemoryExhaustionException
>>             TSSKeyExhaustionException
>
> So, in essence you just want to insert "throwable" in between 
> object and  the rest of the tree.

Yes and, importantly, not allow anything not defined from Throwable 
to be thrown/caught.

> Do you know the design of a program someone is going to write in 
> the  future?
>
> How can you say with utmost surety that under circumstance X that 
> program  has violated it's design and *must* terminate?

Somewhere along the way we've had a gigantic disconnect. Maybe this 
stuff's new to you and I've assumed too much?

A programmer uses CP constructs - assertions, pre/postconditions, 
invariants - to assert truths about the logic of their program, i.e. 
that a given truth will hold if the program is behaving according to 
its design. So its not the case that _I_ say/know anything about the 
program's design, or any such fantastic thing, but that the 
programmer(s) know(s) the design as they're writing, and they 
_assert_ the truths about that design within the code.

>> Notwithstanding all the foregoing, there's a much more 
>> fundamental,
>> albeit little recognised, issue. Computers make a strict
>> interpretation of what we, the programmers, instruct them to do. 
>> Now
>> a contract violation, as I've said, is pure and simple a 
>> statement
>> that your instructions to the computer (or to the compiler, if 
>> you
>> will) are fundamentally flawed.
>
> Correct, and if the program violates it's design it should 
> terminate (in  the most sensible way possible). However, none of 
> this addresses the issue  that you cannot know a future programs 
> design nor whether it should  terminate under any given 
> 'exception'.

Hopefully I've now made that clear.

> So as to clear any confusion, under what circumstance would you 
> enforce  program termination?

When a program violates its design, as detected by the assertions 
inserted into it by its creator(s). It must always do so.

> in other words, which exception or error would you  make 
> un-catchable?

Sigh. I'm trying my best not to be rude, but it seems that you've 
really not bothered to read the posts in this thread before replying 
to them.

1. At no point have I _ever_ said anything was to be uncatchable. 
Indeed, I've specifically, and regularly, discussed the action(s) to 
be taken when catching an irrecoverable exception
2. As long as this debate's been going on, which, IIHIC, is the best 
part of a year, the distinction between errors and exceptions has 
been (ir)recoverability. By convention in D, an Exception is 
recoverable and an Error is irrecoverable, but the latter is not 
enforced, and, as I've shown not possible in D by library extension.

So, no exceptions would be irrecoverable. All errors would be 
irrecoverable. The only place, IMO, where there's a grey area is 
with resource exhaustion, which are theoretically recoverable (since 
they don't mean the program has violated its design) but are often 
practically irrecoverable (by virtue of the ramifications of the 
problem that's caused them).
1 2 3 4 5 6
Top | Discussion index | About this forum | D home