Tony Olekshy wrote:

>  2. Support always and except blocks.  These constructs may be used
>     without requiring a try before the block.  They are dynamic
>     operations which only come into play when they are encountered
>     in the block, in run-time order.

...

> If we take this approach then we know exactly what the following
> code will do.
>
>     { my $p = P->new();
>
>       $p->foo and always { $p->bar };
>
>       except Error::IO { $p->baz };
>       }
>
> We also know when the block propagates unwinding; in particular, it
> doesn't if $p->foo raises an Error::IO exception, unless $p->baz
> throws, but it does if $p->foo raises some other exception (or
> if $p->foo doesn't raise an exception and $p->bar throws).

By rule 2 above, it would seem that if $p->foo raises an Error:IO
exception, that the except block hasn't yet been seen, and therefore the
block should propagate unwinding.

This seems to be a side-effect of separating the except clause into its
own separate statement.  The RFC 119 except clause, which was joined to
the prior statement, affected only that prior statement.  In other words,
the except clause and always clause had different relationships to the
statement to which they were attached.

The always clause is something you always want to do at the end of scope
if you execute it.  I see no problem with making that a separate
statement--it doesn't change the semantics a bit, and it becomes easier
to conditionally execute an always statement, rather than being forced to
execute a conditional always statement.

The except clause, however, was intended to catch the exceptions of only
the statement to which it was attached.  I like the conditional syntax
you have added to the except clause, to allow catching only specific
exceptions.  However, in making it a standalone statement, the semantics
change significantly.  As a clause, the except clause could be attached
to the single statement (or block) from which exceptions it was supposed
to handle might be propagated.  As a statement, however, it seems to have
acquired a block level scope, and, as your example and verbage show, you
haven't quite achieved consistency in your descriptions of it.  The
except statement doesn't apply to the immediately preceeding
statement/block, since it isn't attached, and therefore is different from
an attached except clause in two ways:

1) It must precede any statements that might generate exceptions it
should handle
2) It applies to _all_ subsequent statements in the block

For contrast, the except clause

1) follows the statement/block that might generate exceptions it should
handle
2) applies only to the attached statement/block.

Clearly you could fix up the example to be consistent with the rule.
However, that doesn't achieve the power of the except clause having a
more limited scope than the except statement.  Why is this powerful?
Because since the except clause can be written to apply to a single
statement, there is much less need for determining via the use of other
program state (variables) whether or not to choose to execute the except
clause.  And if the statement to which the except clause is attached
succeeds, the clause is not processed at all.

How can we get both?

One way would be to extend your present catch clause of the try
statement.  When used with try, catch would continue to function as
defined in RFC 88, but as an extension, you could permit catch statements
(same syntax as the catch clause in the try statement) to float within a
block (try or otherwise).  Such catch statements would follow rule 2
above, and would be implemented exactly as you describe.

Leave the except clause with the RFC 119 definition, optionally extended
with your conditional clause between the except keyword and the
subsequent block.  That is, apply it to only the prior statement/block.
The except clause _could_ be called catch--there'd be no syntactic
ambiguity, but I think it would be confusing that:

    {  statement1
        catch Error::IO { statement2 };
        statement3;
        statement4;
     }

would have such different semantics for the conditions under which
statement2 is executed than

    {  statement1;
        catch Error::IO { statement2 };
        statement3;
        statement4;
     }

so I'd rather use a different keyword.  On the other hand, since RFC 88's
catch is tied to the try statement, perhaps it would be better to have
the except clause be renamed to catch, and the catch statement be renamed
to except, so that "catch" would consistently be tied to a prior
statement or block (some cases, tied to a try, other cases, any other
statement), and that except would not be.

> The more I think about having both these options available, the
> better I like it.  Both allow me to be lazier (the latter in
> the case where the exception handling logic is complicated
> enough that doing it carefully is actually lazier).  I get the
> impression some people think I want verbose code, or some sort
> of impractial so-called "ivory tower" solution, but I'm really
> just as lazy as you (probably lazier, but we don't want to debate
> that here ;-)

RFC 119 demonstrates that if you have always and except, you don't need
try.  And if you want to have try-like constructs, you can still build
them, without the try keyword.  So in some sense, it isn't necessary to
have try at all.  I am a strong advocate of having the non-try clauses
and/or statements available, because it allows easy things to be easy; it
allows decomposition of exception handling into small but useful chunks,
and the exception handling code can be placed near the code the might
need it.  Because they are sufficient I see no need for try.  However, I
have nothing against TMTOWTDI, if try turns on enough people's jollies,
or aids in porting code or coders from other languages.

--
Glenn
=====
Even if you're on the right track,
you'll get run over if you just sit there.
                       -- Will Rogers
----- Stuff below this added by NetZero -----



Shop online without a credit card
http://www.rocketcash.com
RocketCash, a NetZero subsidiary

Reply via email to