Posts in this category

Tue, 08 Dec 2009

Perl 6: Failing Softly with Unthrown Exceptions

Permanent link

Most programming languages handle failures with either of two paradigms: failing routines return special values, or they throw exceptions.

Either way has its severe problems: in languages like C it can be very simple to forget to catch such a return value, and very tedious to propagate them to the caller; on the other hand throwing exceptions often clutters the code with way too many try blocks, and it's generally unfriendly if you try to automatically parallelize expressions.

So Perl 6 offers a middle ground: soft or unthrown exceptions. If a routine calls fail("message"), a new Failure object is created and returned from the current routine. That object behaves as an undefined value, which stores the message, file and line information of the fail() location, a backtrace and so on.

When you ask such an object whether it's true or false, or defined or undefined, you'll get a correct answer, and the exception is marked as handled. However if you try to use it as an ordinary value, it turns into an (ordinary) fatal exception. So both of these work:

# Variant 1: no exception thrown

my $handle = open('nonexistingfile');
if $handle {
    .say for $handle.lines;
} else {
    # do something else

# Variant 2

my $handle = open('nonexistingfile');

# throws a fatal exception while calling $handle.lines
.say for $handle.lines;

Now if you do some automatically parallelized operations, a single failure doesn't have to abort the whole operation, and neither is information lost

# divide @a1 by @a2 element-wise, a division by zero might occur:
@a1 »/« @a2;

The API for accessing the Failure objects isn't very mature yet, but the concept stands. See S04/Exceptions for the gory details, as they stand today.

[/perl-6] Permanent link