info-sather
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Exceptions


From: Norbert Nemec
Subject: Re: Exceptions
Date: Tue, 17 Oct 2000 19:07:25 +0200
User-agent: Mutt/1.0.1i

On Tue, Oct 17, 2000 at 07:03:34PM +1300, Keith Hopper wrote:
>      Nobbi disagrees - as follows.  I hope no-one will take offence at my
> fairly blunt comments - no offence is intended!

Don't worry, I'll not be offended that easily. I see there is a major 
disagreement and I'm glad we're able to address it so directly.

Be reading your last message I finally start to understand you're way 
of thinking - that's the first step in the direction of a solution. 
Anyhow - I still disagree... :-)

> > "thread": The exception was definitely raised within the same thread 
> > you are still in! There is no handling of exceptions between threads. 
> > There can't ever be! 
> 
>      Rubbish! Of course there can -- what about a divide by zero - it
> certainly doesn't occur in the program - it is provided by the OS.  What
> about a shared object in a distributed program - there are certainly at
> least two threads involved - one might be thought of as the owner and take
> up the cudgels when an exception is raised - and so on!!!!!

I see - in a distributed program it would certainly make sense to 
handle the errors happening on one machine maybe on a central 
controlling machine. Same may of course be a way to design any other 
multi-threaded program on one machine. This is not a matter of 
exceptions so. One would rather have to catch the exceptions happening 
in any thread just as it is done now and then maybe decide to "handle" 
them by sending a message to somewhere else.

May I cite from the pSather specification:

   5.1 Exceptions in pSather

   Exception handling is complex under any conditions and parallelism only 
makes it worse. The basic design decision for
   serial Sather was to have simple terminating exceptions as described in 
Section 32.1.4 of the manual. For pSather, we
   considered a number of complex possibilities and then settled on the 
simplest possible solution. Exception handling only
   works on a per-thread basis. The code for a thread can include standard 
Sather protect statements. To the extent that
   these deal with any exceptions that are raised in that thread, computation 
can continue. It is a fatal error for an
   exception to be raised in a thread and not handled by that thread. Even so 
it turns out that a stack discipline is not
   enough to handle some of the cases that are discussed below.
   
If you consider changing this in any way, I promise you that you will 
run into serious trouble trying to handle to complexity of the 
solution!

In general: If ever an exception is raised somewhere, the execution is 
stopped at that point, in some way, then, the code of the handler has 
to be started in that moment (or later). Now there is two solutions for 
the handler:

* Either a new thread is started to handle the exception - in that 
case, you would have a new identity for the thread, but effectively, 
you can call it the same as before. On a distributed system, you might 
want to run the handler on a different machine, but there is not much 
reason to implement such a complex solution for it.

* Or, there the exception handler was already waiting for an exception 
to happen. That's the event-handler solution. It is a possible concept 
of exceptions, but I would rather think of it as something different. 

An exception handler is usually meant to do some cleaning up to ensure 
a sane state before leaving a routine. That cannot be done if the 
handler runs somewhere completely different. Of course you might be 
interested to react on any exception happening in your program by such 
an event-handler, but if you want to do so, it would be the correct 
solution to send a message that can then be received by a waiting 
event-handler.

If you really want to make the "raise" statement send the message 
automatically, in which state would you want to leave the raising 
thread? Resuming has no point, since you can't "repair" local variables 
remotely. And resuming at another point is dangerous, because the 
object might be in a inconsistent state and you can't cure its 
privates from outside.

> > "reason": This is simply encoded in the object that is used as 
> > exception type. Every exception must have started at some "raise" 
> > statement in the code. As long as you do not raise two identical 
> > objects in two different raise statements, you can clearly define which 
> > statement in which method is was. Of course with the strange "raise self" 
> > statements that are used in the Sather-W library, that information is 
> > thrown away, because the "exception" variable does refer to the same object
> > no matter which method it was called on.
> 
>      No!!!! And again NOOOOOOOOOOO!
> 
>     The reason relates to a behaviour NOT to an object - and the Required
> Library you will find does raise exceptions on objects other than self -
> indeed that would be the norm in a program too.  The reason has nothing to
> do with the object which is the 'subject' of the exception - it has to do
> with a behaviour specified for the object which is raising the exception -
> the raising agent if you will.

So, if you have an index-out-of-range error, you would call the number 
provided as index the "reason". Correct?

How about an addition overflow in A+B ? Which of the two was "too large"?


I guess I'll just put my idea in Sather code. I really do not know what 
is lacking to what you want:


class MYVERYOWNEXCEPTIONCLASS is
    attr reason: REASON;
    attr object: $OBJECT;
    attr thread: THREAD;
    
    create(areason: $REASON, aobject: $OBJECT, athread: THREAD): SAME is
        res ::= new;
        res.reason := areason;
        res.object := aobject;
        res.thread := athread;
        return res;
    end;
end;

class MYCODE is
    someroutine is
        dosomething;
        raise #MYVERYOWNEXCEPTION(the_gardener, self, this_thread);
               -- don't know how the current thread would be referenced
        dosomethingelse;
    end;
    
    catcher is
        protect
            someroutine;
        when MYVERYOWNEXCEPTION then
            #OUT + "It was the fault of the " + exception.reason.str + "\n";
            #OUT + "He killed our poor " + exception.object.str + "\n";
            #OUT + "In the " + exception.thread.str + "\n";
        end;
    end;
end;


What is missing here, now?

> > OK, interrupts, and asynchronous events in general, have nothing in
> > common with exceptions. 
> 
>      Eeeeeeeeeeek!  They are identical in nature - absolutely identical --
> there is no logical difference between them at all!

Yes, there is! It is the logical difference between a synchronous and 
an asynchronous event. exceptions are directly liked with certain spots 
in the code where they can happen, and if they happen, that's just 
because of the state of the program in that moment. Interrupts can 
happen at just any moment in just any location of the code (not 
cosidering critical regions and stuff like that here).

After an exception has happened it hardly ever makes sense to even 
think about a resume at the same spot. If the divisor was zero, it will 
still be zero then. (It is hardly ever possible for a handler to say 
what it should be instead...) If an exception handler can really solve 
the problem, it would be the straight solution to put the thing into a 
well-defined loop and try again.

After an interrupt has happened, though, there is hardly ever any 
reason why the code should not continue at the same spot. Indeed, you 
should always either continue exactly there or think about aborting the 
program completely. If you do something else, the object where the 
interrupt hit in will most likely be in a very funny state.

> 
> > ------
> 
> > And for your solution with the "err" specification for methods: I see 
> > no difference at all to the solution of specifying the exceptions 
> > raised by a method. Just as it is done in Java. Just as it has been 
> > discussed for at least two years now for Sather.
> 
>      Java, I am sorry to say is brain-dead in this area.  As I have tried
> to explain twice now ther is a subject of an exception which is the object
> the behaviour of which caused the exception to be raised and there is the
> object of the expression - the state of which gave rise to the exception in
> the first place - and the thread which raised the exception which - as you
> say - is frequently - but NOT NECESSARILY the thread to handle the
> exception.
> 
> > ------
> 
> > Finally, a little remark: the quit of an iterator is something very 
> > different from raising an exception. 
> 
>      Grrrrrrrrrrrr!  No it isn't - it isn't at all different. What is
> different is the action taken as a result - in the case of a quit statement
> the action is benign - in the case of the exception the action may be, as
> you say, last ditch!

OK, the two might be combined into one concept, but I do not believe 
that would help in writing understandable programs. "quit" for me 
means: "OK, I'm finished there is nothing more to say". "raise" means 
"Oops, something has gone wrong!"

>      Sorry to disagree so seriously but I have the sneaky feeling that your
> discussioin revolves around a present implementation - not the
> implementation which should be

No - it resolves purely about the concept of an exception. It may be 
bound to languages similar to Sather (Lisp or Prolog would certainly 
not merge with it...) but. Sure, exceptions might be defined and 
implemented in Sather as you describe it, but then the concept would be 
generally changed.

Ciao,
Nobbi


-- 
-- ______________________________________________________
-- JESUS CHRIST IS LORD!
--          To Him, even that machine here has to obey...
--
-- _________________________________Norbert "Nobbi" Nemec
-- Hindenburgstr. 44  ...  D-91054 Erlangen  ...  Germany
-- eMail: <address@hidden>   Tel: +49-(0)-9131-204180



reply via email to

[Prev in Thread] Current Thread [Next in Thread]