Re: RFC 63 (v2) Exception handling syntax

2000-08-12 Thread Peter Scott

At 07:07 AM 8/12/00 -0600, Tony Olekshy wrote:
>One problem I still see with RFC 63 is that there is no syntax for
>doing a string match on the exception's stringification, as in the
>RFC 88 syntax:
>
> except "division by 0" => catch { }
> except qr/div.* by 0/  => catch { }

That's a feature :-)  Selecting exceptions by regex matching on the text 
attribute is a bad idea, IMHO.  What if the message changes in the next 
release?  What if we one day figure out i18n and the message is in 
French?  Note the commonality of RFCs 80 and 85, suggesting that error 
messages be identified by fixed, unambiguous identifiers.

However, RFC 63 could still do it with

 catch {
 my $err = shift;
 switch ($err->message) {
 case /division by 0/ : { }

> > A C block without any C blocks would be pointless,
> > since uncaught exceptions (i.e., all of them) would be rethrown.
>
>Whoa.  What about making sure that if a file is opened then it
>is closed, even if the processing between open and close throws,
>as in:
>
> open(*F, ">foo") or throw ...;
>
> try { ... }
>
> finally { close F or throw ...; }

Ah, thanks.  Hadn't thought about using a finally block there.

>It's a pleasure to work with you on these matters.

Ditto.

>   It appears
>to me that Peter's approach in RFCs 63 and 80 represents the
>perspective that the exception is the key and handling is just
>what you do with it, whereas my approach in RFCs 88 and 96 is
>that handling exceptions is the key, and the exceptions are just
>what you happen to be handling.

I think it's important to remember that we're just coming up with ideas 
here for the people who make the design decisions on P6 to chew over, not 
coming to final decisions ourselves.  So I view multiple overlapping RFCs 
as a good thing; they indicate that there is a common need, that there are 
differing sub-needs, and leave open the possibility for a greater genius to 
find a solution that makes everyone happy.



--
Peter Scott
Pacific Systems Design Technologies




Re: RFC 80 (v2) Exception objects and classes for builtins

2000-08-12 Thread Peter Scott

At 07:07 AM 8/12/00 -0600, Tony Olekshy wrote:
>Peter Scott wrote, in RFC 80 (v2):
> >
> > =item id
> >
> > Unique numeric identifier, assigned by perl developers.
>
>I'm loath to bother everyone with this

I've redirected to perl6-language-flow.  They're supposed to enjoy being 
bothered with it :-)

>, but to me the id of an
>object should be unique to each *instance* of the class.  If we had
>
> my $e = Exception->New(id => "ABC.1234");
> my $f = Exception->New(id => "ABC.1234");
>
>then $e and $f would have the same id, but be different objects.

Yes, the implicit registry bothers me too - not for the core: I figure the 
perl developers can manage a little enumeration class - but for external 
stuff.  CPAN could conceivably work since they already have a registry for 
the naming hierarchy, but what about when you want to write an in-house 
thingy and make sure the ids don't collide with anything else you 
get?  Number ranges for user space (e.g., negative numbers) are all well 
and good, but eventually you'll have two or more separate things both 
living in user space but constructed independently.

I was attempting to carry RFC 85 to its logical extension, but perhaps I 
stretched it too far.

I think it's not as bad as you imply though.  We could disambiguate id tags 
by checking the exception class name, since it's reasonable to assume that 
anything throwing an exception in a particular class will coordinate ids 
with everything else doing the same.

> > Line number exception was thrown at.
> > File exception was thrown in.
>
>Should this be line thrown at or line constructed at?  Does anyone
>care?

There is an issue of how far up the call stack you should go.  If I write

main.pl:
   1  try {
   2 foo($obj);
   3  };
   4  sub foo {
   5 $_[0]->bar();
   6  }

Foo.pm:
100  sub bar {
101 pling(shift);
102  }
103  sub pling {
104 throw Exception::Baz unless blech(shift);

should the (file, line) be: (main.pl, 2), or (Foo.pm, 101) or (Foo.pm, 
104)?  Clearly if you wrote Foo.pm you'd like the last one, and if you 
didn't, you'd like the first one.  Well, probably you'd want all of 
them.  Hmm - what if we made line() and file() return arrays?  Then we'd 
also like uncaught exceptions that result in program death to at least have 
the option of a confess() backtrace, and the data would be in the object.

> > Stringifying the object itself will yield the C attribute.
>
>Or perhaps a formatted combination of a subset of the attributes,
>as in RFC 96?

Or the confess() I just suggested above, yes.


--
Peter Scott
Pacific Systems Design Technologies




Re: RFC 63 (v2) Exception handling syntax

2000-08-12 Thread Tony Olekshy

Peter Scott wrote, in RFC 63 (v2):
>
> This RFC is very similar to RFC 88, which has slightly different
> syntax and adds functionality for adding exceptions to a stack.
> While this author considers that to be going a bit too far (he's
> tried it before and found he never made use of anything under the
> top level of the stack), he wouldn't mind if RFC 88 got adopted
> instead.  This RFC is attempting to stake out a more minimalist
> position.

The author of RFC 88 (that's me) agrees with you that it is going
a bit too far.  In fact, we mainly use the exception stack to
generate those fancy tracebacks into server logs, not to catch
them per se.  I'm planning to revise RFC 88 to pull out the default
stack handling, but to provide hooks to allow such a stack to be
maintained via use of a module.  Then, it's available for the fancy
stuff, and the except => sub { } => catch { } syntax and/or the
catch { switch } syntax can be used to deal with those rare special
cases where one would want to examine the stack (if it's enhooked).

One problem I still see with RFC 63 is that there is no syntax for
doing a string match on the exception's stringification, as in the
RFC 88 syntax:

except "division by 0" => catch { }
except qr/div.* by 0/  => catch { }

That's why RFC 88 provides both this form and the "except isa"
form.  (Note that I'm planning to revise RFC 88 to require the
form "except match => 'foo'" or "except match => qr/foo/" to
remove the difficult rule about the reserved lower-case stuff,
and to add forms like "except tag => 'ABC.1234'" and "except
severity => /^(Fail|Fatal)$/', depending on how RFC 96, A Base
Class for Exception Objects, pans out.)

I'm also planning to revise RFC 88 to take a listref of strings
or REs wherever it currently takes a single string or RE, as in
the "except match" and "except isa" forms.  Thanks to everyone
who participated in the discussion on this matter.

> A C block is a Java C block; it gets executed
> after the C block, after any C blocks, but before any
> uncaught exception is re-thrown.  In this case we were inheriting
> syntax from Perl rather than another language.

> Some people think it should be even more minimal by using C
> instead of C, and C instead of multiple C
> blocks.

As I mentioned elsewhere, it seems to me that continue connotes some
sort of looping thing, not "whether or not unwinding".  I'd much
rather take the hit of a new but traditional exception handling
keyword like "finally", than the hit of conceptually overloading
continue in this case.  Minimalism only goes so far, in the sense
that even Bauhaus and wabi sabi tend to have doors that are not the
same as windows.  And I'm no lexicographer, but I think finally
pre-dates Java.

There's another thing too.  If we use finally instead of continue,
then we can continue to maintain a Perl 5 implementation.  This
means that (1) we can continue to experiment with the implementation
and build regression tests before Perl 6 is born, and (2) Perl 5
programs and modules can begin to migrate to the new exception object
and exception handling mechanism while still running in Perl 5.  The
value of these benefits may be greater than epsilon.

> A C block without any C blocks would be pointless,
> since uncaught exceptions (i.e., all of them) would be rethrown.

Whoa.  What about making sure that if a file is opened then it
is closed, even if the processing between open and close throws,
as in:

open(*F, ">foo") or throw ...;

try { ... }

finally { close F or throw ...; }

or making sure an object's clean-up routine is called, in cases
where the default GC doesn't do the job for you, as in:

my $o;

try { f ( $o = SomeClass->New ); }

finally { $o and $o->Done; }

> The C function is just syntactic sugar for creating
> a new exception class, it merely amounts to @EXCEPTION::ISA =
> 'Exception'.

That reminds me, I need to revise RFC 96 to add a throw constructor
and to allow some sort of construct like:

use Exception Class => "Database::Write";

> RFC 80 proposes standard exception classes and methods for
> core exceptions.

I also submitted RFC 96, which tries to address the stuff that
is needed for extending beyond builtins while maintaining a
standard Perl OO implementation and seperating the exception
handling stuff from the exception class.  Rereading RFC 80, I
realize that they are closer than I thought, each emphasising
different aspects of the problem.  No doubt we can eventually
merge these, as may become the case with 63 and 88 as well.

It's a pleasure to work with you on these matters.  It appears
to me that Peter's approach in RFCs 63 and 80 represents the
perspective that the exception is the key and handling is just
what you do with it, whereas my approach in RFCs 88 and 96 is
that handling exceptions is the key, and the exceptions are just
what you happen to be handling.

We should be able to do a pretty good job of putting these two
p

RFC 63 (v2) Exception handling syntax

2000-08-12 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Exception handling syntax

=head1 VERSION

  Maintainer: Peter Scott <[EMAIL PROTECTED]>
  Date: 8 Aug 2000
  Last-Modified: 12 Aug 2000
  Version: 2
  Mailing List: [EMAIL PROTECTED]
  Number: 63

=head1 ABSTRACT

This RFC proposes an exception handling syntax for Perl 6 adapted from
that used in Graham Barr's C module.

=head1 DESCRIPTION

An exception handling mechanism is proposed with the following syntax:

 exception EXCEPTION

 try BLOCK catch [EXCEPTION [, ...] ] BLOCK ...
 try BLOCK catch [EXCEPTION [, ...] ] BLOCK continue BLOCK

 throw EXCEPTION [ (attributes) ]

Exceptions thrown in the C block cause immediate termination of
processing of the C block.  Perl then looks through the C
blocks in order for one which either names the class the exception
belongs to, or which names none, therefore catches all.  If it finds
one, it executes the code in that block.  It then executes any
C block.  At that point, if the exception had been caught,
processing continues with the next statement; if it was not caught,
it is propagated up to any enclosing C block and the process
repeated.  The exception object is passed into each block in C<$_[0]>.

An uncaught exception with no enclosing C block causes the program
to C with the text in the C attribute of the exception,
which is what the exception stringifies to.

A C block is a Java C block; it gets executed after
the C block, after any C blocks, but before any uncaught
exception is re-thrown.  In this case we were inheriting syntax from
Perl rather than another language.

Note that C is a keyword, not a function.  This is solely so that
a C<;> is not needed at the end of the last block, since so many people
are bound to think it shouldn't be there and forget.

There is debate over whether C should be C so as not to use
another keyword.  Since it has different semantics (rethrows uncaught
exceptions), it should not be C; but if this happens, then surely
C should be retired since it is so similar there would be
confusion over what to use for exception handling.  And no-one would
get the semicolons right :-)

A C block without any C blocks would be pointless, since
uncaught exceptions (i.e., all of them) would be rethrown.

While C and C are new keywords, C and C
don't need to be; they're just functions.

=head2 Exceptions

Exceptions are objects belonging to some C class.  Cing
an exception creates the object; therefore, C above is just a
class name.  C lets you subclass C to create them;
C appears to be a better name for a core functionality.

The C function is just syntactic sugar for creating a new
exception class, although it merely amounts to C<@EXCEPTION::ISA = 
'Exception'>.

RFC 80 proposes standard exception classes and methods for core
exceptions.

=head2 Examples

These examples assume some core exception classes, although the
mechanism can be implemented even if core exception classes aren't.
The nature of exceptions is that they are most useful on lengthy code;
code brief enough to be a readable example also makes a functionally
poor example.

 exception Exception::MyDB;
 sub foo {
 open_database();
 # database-munging code
 throw Exception::MyDB(message => 'permission denied');
 close_database();
 open_network_connection();
 # network munging code
 throw Exception::IO(message => 'timeout');  #  In Socket.pm, perhaps
 close_network_connection();
 }

 try {
 foo();
 } catch Exception::MyDB, Exception::DBI {
 close_database();
 # other stuff
 } catch Exception::IO {
 close_network_connection();
 # other stuff
 } catch {
 my $err = shift;
 warn "Some other kind of error in foo: $err\n";
 throw $err;  # Re-throw exception (just 'cuz we wanted to)
 }

=head1 IMPLEMENTATION

A C is just a C passed an object that stringifies to the
message you will die with if nothing catches the exception; therefore
users can use code that throws exceptions without using the exception-handling
mechanism.  They should also be able to wrap a C block around code
that doesn't know about exceptions but does call C, and have that
caught as well; perl should turn the C text into an exception object
with the same text, in the base C class.

=head2 $SIG{__DIE__}

<$SIG{__DIE__}> needs to be triggered only as a I resort
instead of firing immediately, since it messes with the mind of this and
every other decent exception handling mechanism.  Perhaps it should be axed
altogether.

=head1 NOTES

This RFC is very similar to RFC 88, which has slightly different syntax
and adds functionality for adding exceptions to a stack.  While this author
considers that to be going a bit too far (he's tried it before and found he
never made use of anything under the top level of the stack), he wouldn't
min

RFC 96 (v1) A Base Class for Exception Objects

2000-08-12 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

A Base Class for Exception Objects

=head1 VERSION

Maintainer: Tony Olekshy <[EMAIL PROTECTED]>
Date: 12 Aug 2000
Version: 1
Mailing List: [EMAIL PROTECTED]
Number: 96

=head1 ABSTRACT

A number of topics in the Perl 6 RFC discussions have touched on
the concept of a sanctioned or canonical base class for exception
objects.

This RFC considers a basic proposal for a base class for exception
objects that can be used with core Perl, traditional eval, die, and
$@ functionality, and with exception handling mechanisms like RFC 63
and RFC 88.

=head1 DESCRIPTION

One of the attributes of an exception object is its class name.
This can be changed via inheritance, and a hierarchy of isa
relationships can be arranged.  Exception handing mechanisms can
arrange to have catch behaviour depend on these relationships.

=head2 Instance Variables

The following exception object instance variables are supported by
this base class.

tag

This is a string which module developers can use to assign
a unique "identifier" to each exception object constructor
invocation in the module.

What should the default be if not otherwise specified?

severity

This is some sort of "priority" (such as info v/s fatal) on
which handing can be based.  The details need to be worked
out.

What should the default be if not otherwise specified?

message

This is a description of the exception in language intended
for the "end user".  This is the only required ivar, so as
such the constructor treats it specially.

debug

This is a place for additional description that is not
intended for the end user (because it is "too technical"
or "sensitive").

file

The file from which the constructor was called.

line

The line from which the constructor was called.

object

If the exception is related to an object, it can be
specified here.  Should this be a weak reference?

sysmsg

This a place for the internal exceptions raised by Perl
to record system information, along the lines of $!.

=head2 Methods

Only constructor and accessors so far.

=head1 IMPLEMENTATION

This is a bit minimalist, but it's a start.

package Exception;

use overload '""' => sub {

my $t = exists $_[0]->{tag} ? $_[0]->{tag} . ": " : "";

exists $_[0]->{severity} and $t .= "($_[0]->{severity}) ";

$t .= $_[0]->{message} =~ /\S/

? $_[0]->{message} : "anonymous exception.";

$t }

sub new
{
my ($C, $msg, %A) = @_;

exists $A{file}   or $A{file}   = caller ...
exists $A{line}   or $A{line}   = caller ...
exists $A{sysmsg} or $A{sysmsg} = magic  ...

bless {message => $msg, %A}, ref $C || $C;
}

sub tag  { @_ > 1 and $_[0]->{tag}  = $_[1]; $_[0]->{tag}  }
sub severity { @_ > 1 and $_[0]->{severity} = $_[1]; $_[0]->{severity} }
sub message  { @_ > 1 and $_[0]->{message}  = $_[1]; $_[0]->{message}  }
sub debug{ @_ > 1 and $_[0]->{debug}= $_[1]; $_[0]->{debug}}
sub file { @_ > 1 and $_[0]->{file} = $_[1]; $_[0]->{file} }
sub line { @_ > 1 and $_[0]->{line} = $_[1]; $_[0]->{line} }
sub object   { @_ > 1 and $_[0]->{object}   = $_[1]; $_[0]->{object}   }
sub sysmsg   { @_ > 1 and $_[0]->{sysmsg}   = $_[1]; $_[0]->{sysmsg}   }

=head1 IMPACT

Once a standard set of attributes is decided on, RFC 88 can be
revised to provide exception tests like:

except tag => "ABC.1234" => catch { ... }

except severity => "Fail" => catch { ... }

=head1 ISSUES

How to extend ivars and control namespace?

How to extend methods and control namespace?

Default values for tag and severity?

How to categorize severity?

How to arrange the exception class hierarchy for the Perl core?

How to tag exceptions in the Perl core?

What assertions should be placed on the instance variables?

What should stringification return?

=head1 REFERENCES

RFC 70: Allow exception-based error-reporting.

RFC 80: Exception objects and classes for builtins.

RFC 63: Exception handling syntax proposal (Error.pm)

RFC 88: Structured Exception Handling Mechanism (Try.pm)