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

2000-08-11 Thread Peter Scott

Redirected to perl6-language-flow.

At 12:23 PM 8/11/00 +0100, Graham Barr wrote:
On Thu, Aug 10, 2000 at 07:30:53PM -0700, Peter Scott wrote:
  If we're really talking about new keywords, we wouldn't need a ; at the 
 end
  of the last block; it's only needed at the moment because eval is a
  function, not a keyword.  I would vote for the keywords only because 
 people
  are going to forget the ; otherwise.

That maybe a reason to use `try' instead of `eval'. Another difference would
be that try will rethrow uncaught error, eval does not. And of course
a die in any catch block would throw an error to a try/eval block up the
stack, after running the continue block. So adie;   in the catch
block would rethrow the same error.

If we did use 'try', would we retire the block form of 'eval'?  It could be 
confusing to have a keyword with almost identical but subtly different 
semantics to a function.


--
Peter Scott
Pacific Systems Design Technologies




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

2000-08-11 Thread Tony Olekshy

I've moved this from perl6-language to perl6-language-flow.

Tony Olekshy wrote:

 With the approach proposed in RFC 88 (Structured Exception
 Handling Mechanism), you could write that as:

   try {
   } catch {
   switch ($_[0]-name) {
   case IO { ... }
   case Socket { ... }
   }
   }

Graham Barr wrote:
 
 the error are objects, so you need to allow for inheritance.

I was just trying to point out that RFC 88 uses try {} catch {}
instead of try {} otherwise {}, and that the current error comes
into the catch block via @_ (as in RFC 63), so one doesn't need a
"global".

Sometimes you want to collect all the catching into one clause (if,
say, there was lots of common code and little varying code).  In
other cases, you want a seperate clause for each exception (if, say,
there is little common code, then the seperate clauses handle the
switch for you, which is more DWIM).  That's why RFC 88 allows you
any combination of these operations, as in:

try {
}
except isa = "Foo" = catch { ... }
except isa = "Bar" = catch { ... }
except else = catch { ... }

Again, the differences between this and RFC 63's approach are, in
this case, only syntactic.

Yours, c, Tony Olekshy



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

2000-08-11 Thread Tony Olekshy

I've moved this from perl6-language to perl6-language-flow.

Graham Barr wrote:

 eval {
 # fragile code
 }
 else {  # catch ALL exceptions
 switch ($@) {
 case __-isa('IO') { ... }
 case __-isa('Socket') { ... }
 else   { ... }
 }
 }
 continue {
# code always executed (ie finally)
 }

Chaim Frenkel wrote:

 Nice.

Hmm.  The eval was commented to indicate fragile code, which is
implied if the keyword try is used.  The else was commented to
indicate a catch, instead of saying catch, and the continue was
commented to indicate a finally, instead of saying finally.

There does seem to me to be some benefit to the clarity of the
RFC 88 approach, which supports both:

try { }
except isa = 'IO' = catch { }
except isa = 'Socket' = catch { }
except else= catch { }
finally { }

and:

try { }
catch {
switch ($_[0]) {
case __-isa('IO') { ... }
case __-isa('Socket') { ... }
else   { ... }
}
}
finally { }

Yours, c, Tony Olekshy



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

2000-08-11 Thread Graham Barr

On Fri, Aug 11, 2000 at 09:36:32AM -0700, Peter Scott wrote:
 Redirected to perl6-language-flow.
 
 At 10:39 AM 8/11/00 -0400, John Porter wrote:
 Piers Cawley wrote:
  
   The (continue|always|finally|whatever) clause will *always* be
   executed, even if one of the catch clauses does a die, so you can use
   this to roll back the database transaction or whatever else was going
   on and restore any invariants.
 
 Which makes me think that it would be nice if the continue block could
 come before the catch block(s):
 
  establish_invariants();
  try {
  something_risky();
  }
  continue {
  restore_invariants();
  }
  catch {
  handle_error_assuming_invariants_restored();
  }
 
 

 The only point of using the continue block as you suggest is if there are 
 multiple catch blocks, otherwise you'd just do

Hm, my understanding is that the continue block would be run it there was
an error or not.

So with no errors you do

  execute try
  execute continue

but if there was an error

  execute try
- die
  execute continue
  execute catch

Graham.



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

2000-08-11 Thread Tony Olekshy

Peter Scott wrote:
 
 John Porter wrote:
 
  Which makes me think that it would be nice if the continue block
  could come before the catch block(s).
 
 I get where you're going with this but it breaks the paradigm too
 much.  Now you need a 'finally' block again.

Sometimes you want before, sometimes after, as in:

try {
open(*F, "foo") or throw "Can't open foo.";

print F ...;
}

finally { close F or throw "Can't close foo."; }

unwind { attempt_to_log_error_message($_[0]); }

which can also be written as:

try {
try {
open(*F, "foo") or throw "Can't open foo.";

print F ...;
}

finally { close F or throw "Can't close foo."; }
}

catch { attempt_to_log_error_message($_[0]); throw; }

The exception handling mechanism considered in RFC 88 has both
pre-finally and post-finally exception trapping clauses, named
catch and unwind.

The basic syntax considered in RFC 88 is:

try { ... throw ... }   #  try clause

except TEST = catch { ... }#  0 or more

catch { ... }   #  0 or more

finally { ... } #  0 or more

unwind { ... }; #  0 or 1

The basic semantics are:

  * The try clause is evaluated.

  * Each catch clause is invoked, but only if an exception has
been raised since the beginning of the try statement, and
the catch clause's except TEST is true or is not given.

  * Each finally clause is invoked whether or not an exception
has been raised since the beginning of the try statement.

  * The unwind clause, if any, is invoked if an exception has
been raised since the beginning of the try statement, and
it has not been cleanly caught.

  * After processing all clauses, try unwinds (dies) iff any
exception wasn't cleanly caught.

An exception is considered to be "cleanly caught" if it was in
the try clause, and it triggered a catch clause, and no catch
or finally clause raised an exception.

Yours, c, Tony Olekshy