On RFC 88: Serendipity while throwing a string.

2000-08-28 Thread Tony Olekshy

I have been working on the Perl 5 reference implementation of
RFC 88 functionality (Try.pm, which is currently available at:
http://www.avrasoft.com/perl6/try6-ref5.txt ), and I stumbled
across the following result.

If you are writing some code, and there is a "throw" subroutine
in scope, and there is a package Exception in scope and it has
a "throw" subroutine, then Perl 5 can tell the following apart
(search for the /!throw-3/ regression test in try6-ref5.txt):

throw "A Message";  # Calls the subroutine.

throw  Exception;   # Calls the method.

throw "A Foo Message",  tag = "ABC.1234";

throw  Exception "Foo", tag = "ABC.1234";

I don't know about you, but I think this is cool.  Talk about
DWIM!  Good old Perl.

So now, in Try.pm, If you throw a string, you get an Exception
anyway:

throw "A Message", ...;

is now the same as:

throw Exception "A Message", ...;

You can't say Cthrow $@ to re-raise an exception any more,
but you can say $@-throw or use a simple bare Cthrow;!
And Cthrow; with @@ == 0 raises a simple Exception!

I'll modify RFC 88 to change the throw syntax from:

throw := throw E message options ;

E := class | object
to:
throw := throw class message options ;
 | throw string options ;
 | throw;

and make the appropriate changes to the semantics.  And of course,
Ctry should accept an additional hook parameter that specifies
the class into which to instantiate string throws.

Seems obvious in retrospect; we already had class and string,
why did E have to be class | object?  Ah well, serendipity
is like that, I suppose.

Yours, c, Tony Olekshy



Re: Structured exception handling should be a core module.

2000-08-28 Thread Peter Scott

At 10:13 AM 8/25/00 +0200, Bart Lateur wrote:
You're citing my objection for merging in $@ with the rest of the error
variables. $@ currently is the "eval failed" flag, irrespective of what
else failed. We *must* have such a flag. If $@ and $! would be merged,
$! will have to be cleared if the eval doesn't fail, just like $@ is
now.

Yes.  Basically, you can think of the new $! as getting done to it whatever 
was last done to any of the set of $@, $!, $^E, and $? in the current Perl.
Well, I doubt it will be that simple :-)

--
Peter Scott
Pacific Systems Design Technologies




Re: Structured exception handling should be a core module.

2000-08-28 Thread Peter Scott

At 01:42 AM 8/25/00 -0600, Tony Olekshy wrote:
Peter Scott wrote:
  If $@ and $! are merged, then in code like
 
   try {
   system_call_that_fails();
   more_stuff_that_succeeds();
   }
   finally {
   }
 
  does the finally block think there is a current exception or not?
  $!  was set by the failed system call, but nothing died or threw.
  If $@ is put into $! instead, how does the finally block know that
  it's not an exception?  ! ref($!) ...?

I think it is imperative that if Perl has die and eval then it must
have a flag that indicates *only* whether or not eval returned via
normal local flow control or via non-local unwinding started by a
die.  Otherwise, I can see no way any quasi-reliable non-local flow
control can be extened by writing blocks of local flow-control code.

So if open, for example, can set $! without invoking die, then $!
and $@ must not be merged.  As I read it, 151 would (as currently
promulgated) not meet my requirement for the unique nature of a
$@-style variable.  I don't think overloading ref to pick off true
exceptions would make me happy either ;-)

Actually, think about it some more.  Why not?  If you want to implement RFC 
88 as a module, then the ugliness, if there be any, of testing ref $! 
instead of $@ is tucked away in one place only.  The end user is not 
bothered by any of this because if they inspect $! as a string, they'll get 
the error message no matter what happened.

I think that RFC 151 should be *merged* into RFC 80.

RFC 151 seeks to simplify the space of error variables for people doing 
very short things without exceptions.  I really don't want to muddle the 
issue with structured exceptions; I just want to make sure it doesn't 
obviate any of RFC 88.

   RFC 80
should define a simple set of lower-case system-reserved fields
to be used for signalling fault information by the Perl 6 core.
RFC 80 should also define a mapping from this simple fault-hash
into a proper Exception object (using, oh, say reference to a
blessed copy of said fault-hash).

Now, hold on to your hat, %@ should the name of this fault-hash...
 $@{type}"IO::File::NotFound"
 $@{message} "can't find file"
 $@{param}   "/foo/bar/baz.dat"
 $@{child}   $?
 $@{errno}   $!
 $@{os_err}  $^E
 $@{chunk}   That chunk thingy in some msgs.
 $@{file}Source file name of caller.
 $@{line}Source line number of caller.

This is just an object in sheep's clothing.  Worse, you've not only not 
merged $!, $^E, and $@, which was the goal of RFC 151, you've made their 
names longer.  Breaking out all those attributes is fine, for them that 
wants it; but then do it in an object.  I'm trying to define an independent 
proposal in RFC 151 for the folk who don't want to use exceptions and don't 
want to scratch their heads to figure out what error variable to look at.

%@ should not contain a severity or fatality classification.

*Every* call to a core API function should clear %@.

Internally, Perl can use a simple structured data type to hold the
whole canonical %@.  The code that handles reading from %@ will
construct it out of the internal data on the fly.

If Cuse fatal; is in scope, then just before returning, each core
API function should do something like: %@ and internal_die %@;

AFAICT this isn't necessary.  If a core function experiences an error, if 
Fatal is in scope, it dies by throwing an exception in $! which stringifies 
to the usual error text.  If it isn't in scope, it sets $! to that error 
text.  Good backwards compatability karma.

The internal_die becomes the one place where a canonical Exception
can be generated to encapsulate %@ just before raising an exception,
whether or not the use of such canonical Exceptions is controlled by
a pragma such as Cuse exceptions;.

--
Peter Scott
Pacific Systems Design Technologies