On Mon, Jun 02, 2008 at 12:31:34PM +1000, Paul Fenwick wrote:
> G'day p6l and p5p,
> I'm currently working on the 'autodie' pragma for Perl 5, which is 
> essentially 'Fatal' but with lexical scope.  It's similar to the 'fatal' 
> pragma described in S04/Exceptions.
> autodie is implementing an exception hierarchy for in-built functions. 

One little problem at the outset here is that Perl 6 has almost no
concept of "built-in" or "CORE", except insofar as the Prelude happens
to choose to import certain subs into the user's scope by default.
Once you actually start parsing and calling functions, there is
no distinction at all between different versions of "open", say.
As chromatic points out in his inimitable style, a hierarchical
classification often forces the user to make meaningless choices in
such a case.

It's much like in the old days when configuration scripts switched
from being OS-based to feature-based, because you never knew which
OS's were going to implement which features when...

> Essentially we have a tree that looks like:
>   :all
>       :USER
>       :CORE
>           :math
>               atan2
>           :io
>               :file
>                   open
>                   close
>               :filesys
>                   opendir
>               :socket
>                   accept
>                   bind
>                   connect
>                   ...
> Currently, when testing exceptions from autodie, we can use:
>       given ($@) {
>               when (undef)   { say "No errors here" }
>               when ('open')  { say "Open died" }
>               when (':file') { say "Some sort of file error" }
>               when (':io')   { say "Some other error" }
>               when (':CORE') { say "Some other CORE error" }
>               when (':USER') { say "A non-CORE error" }
>               when (':all')  { say "Any autodie exception at all." }
>                 default        { say "Not an autodie exception." }
>       }

That may be what we have to do for Perl 5, but from the Perl 6
viewpoint it's duplicating information that should derive directly from
the type and introspection systems.  P5 tends to force you to represent
a lot of information as strings that is more naturally represented by
the metamodel in P6.  For instance, functions are real objects in P6,
and can have other methods than just the "invoke" method.  If you want
to tell a function how to behave, you might just talk to it directly...

> There's a 5 minute presentation on what autodie is and how it currently 
> works at:
>       http://pjf.id.au/blog/?position=540
> This also looks very similar to what I remember is the desired plan for P6 
> exception handling, although my memory may be playing tricks on me as I 
> can't seem to find the document where I read this.

That's because it would be S33, which hasn't been written yet... :)

> So, why does p6l care?  Well, if there's already a p6 exception hierarchy 
> designed for built-ins, I'd like to use it.  It saves me work, and saves 
> surprises for the developers.  If there isn't a p6 exception hierarchy yet, 
> then I'd like for p6 to have the option of stealing mine, for essentially 
> the same reasons.

We could use someone of a practical turn of mind to write S33 for us.
But it does need to fit into P6-Think, and P6's exception-handling
model is rather different from P5's.  To wit:

    * All exception variables are unified into the $! variable.
    * $! is now lexical (but dynamically visible to subcalls).
    * As with autodie, fatality is lexically scoped, but that's because
       the dynamic scope asks the outer lexical scope what it wants to do
       when you call fail().
    * Instead of return bare "undef", failing functions generally
        return "unthrown exceptions" that keep all the info that
        would have been in a thrown exception.
    * The default is still not to throw an exception, but any unhandled
        exceptions are eventually reported as if they had been thrown
    * Throwing an exception does not automatically unwind the stack
        one of the handlers asks for that.
    * Warnings are just exceptions that print their message and then
        "forget" to unwind the stack.
    * Exception handlers run in the lexical context of the block being
    * Exception handlers run in the dynamic context of the code that is

This is mostly discussed in S04.

I do think that one practical difference will be that people aren't
going to be terribly interested in enumerating which functions pay
attention to the current exception policy, since the new default
policy will hopefully be a bit saner than P5 can manage, and the
it will likely be possible to apply policy changes more consistently
when policy changes are needed because the language is designed
to be mutable.

There is also going to be somewhat less cultural pressure toward
a throw-by-default model in programs that trying to do parallel
operations.  Generally you want to propagate exceptions through as
data rather than control flow in that case.  If you're processing the
values of 100 sensors on your rocket ship, you don't want to blow up
(literally, perhaps) your parallel attitude-adjustment algorithm
merely because one of the sensors when haywire.  And the world
seems to be trying to force us into massive parallelism these days,
whether we like it or not.  Just as it would be ludicrous to throw an
"exception" on the entire Web when one bit of it becomes undefined,
so too our programs are going to have to be written in a more failsoft
fashion that treats errors as data rather than control flow.

And I think "interesting values of undef" is P6 idea that P5 could
usefully incorporate without much damage.

> Questions I'm seeking answers to are:
> * Is there a document that describes the current p6l exception hierarchy? 
> My searching skills seem to be impaired today.

I've been putting off writing S33 until the various implementations come
up with their own ideas of what will be necessary, since this is an area
that is easy to overengineer.  Certainly, though, some of our current
implementations are trying to run on top of Perl 5, so we have to take
the input of P5 folks into account too...  :)

But there is increasing need to write S33--I've noticed on #perl6
that the errors produced by the various implementations when someone
launches a multi-bot "perl6:" query can be wildly divergent.  It would
be nice if those error messages tended to converge over time.

> * Does anyone have any input they'd like to make before I start fleshing 
> out the hierarchy for p5 autodie?

As chromatic suggested, it would be good to use some kind of role-ish
mixin idea (with or without Moose) instead of hierarchies of strings.

> * Is this an appropriate question for p6l?

I dunno--you're dragging us back down from the stratosphere of theory
to the troposphere of practice.  I don't know if everyone here can
stand the shock. :)

> While it relates to a p5 
> pragma, I hope to make the behaviour as compatible with p6 as possible.

Yes, I don't expect we can keep things entirely lined up, but it would
be nice to avoid gratuitous divergence if we can.


Reply via email to