Re: RFC 80 (v1): Exception objects and classes for builtins
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
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
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
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
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