December 2008 Archives

Perl 6 - Given/When

| 235 Comments | No TrackBacks

Today I fixed the majority of the issues with Rakudo's 'when' blocks. When blocks do smartmatching against the current topic. For example, this:

when 'foo' { ... }

could also be written approximately like this:

if $_ ~~ 'foo' { ... }

The biggest difference is that 'when' blocks automatically break out to the innermost scope that has $_ as one of its formal parameters (either explicit or implicit), so:

for @numbers {
    when 1..5 { say 'low' }
    when 6..10 { say 'high' }
}

Could also be written as:

for @numbers {
    if $_ ~~ 1..5 { say 'low'; break }
    if $_ ~~ 6..10 { say 'high'; break }
}

(Which currently doesn't work in Rakudo, as we don't have control exceptions on loops handled properly yet.)

this lets us use the 'given' block, which just sets the topic for the block, to implement an idiomatic switch statement in Perl 6:

given $foo {
    when 'A' { say 'got A' }
    when 'B' { say 'got B' }
    when 'C' { say 'got C' }
    when '1' { say 'got 1' }
    when '2' { say 'got 2' }
    when '3' { say 'got 3' }
    when /foo/ { say 'matched a regex' }
    when 1..100 { say 'matched a range' }
    when 'etc' { say 'you know... like this.' }
    default { say 'When all else fails...' }
}

There's a handler for CONTINUE exceptions around every 'when' block to continue on through the block, so if you want to fall through, you just say:

given $num {
    when '3' { say 'got 3'; continue }
    when 1..100 { say 'got from 1 to 100' }
}

Non-fatal exceptions

| 153 Comments | No TrackBacks

Parrot's exceptions have a 'severity' attribute to indicate, of course, how severe the exception is. The current severities are: (taken from runtime/parrot/include/except_severity.pasm

EXCEPT_NORMAL   
EXCEPT_WARNING  
EXCEPT_ERROR    
EXCEPT_SEVERE   
EXCEPT_FATAL    
EXCEPT_DOOMED   
EXCEPT_EXIT

For a long time now, the spec has said that non-fatal exceptions shouldn't cause termination of the program, but should result in the message being printed and normal execution resuming. This hasn't been the case until today. It was a pretty simple change, but should make some things much nicer in the future.

Here's a simple program demonstrating this behaviour:

.include 'include/except_severity.pasm'
.sub main :main
    say 'before the warning'
    $P0 = new 'Exception'
    $P0['severity'] = .EXCEPT_WARNING
    $P0['message'] = "\tOMG something is kinda wrong"
    throw $P0
    say 'after the warning'
.end

And here's the output:

[sweeks@kweh parrot]$ ./parrot et.pir
before the warning
    OMG something is kinda wrong
after the warning

I've also updated Perl 6's warn() to use a non-fatal exception, meaning that these can now be caught.

Currying in Perl 6

| 139 Comments | No TrackBacks

There is still quite a lot of low-hanging fruit in Rakudo.

I checked on IRC today during a break in the class I'm teaching to see jhorwitz asking for currying in Perl 6, which is spelled like:

my $curried = &function.assuming(...);

A few minutes later, I committed an implementation of it. Here is the currying patch for Rakudo. It's about the same size as the last patch I mentioned here. Here are the tests we're now passing:

sub tester(:$a, :$b, :$c) {
"a$a b$b c$c";
}

my $u = &tester.assuming(b => 'x');
is $u(a => 'w', c => 'y'), 'aw bx cy', 'currying one named param';

my $w = &tester.assuming(b => 'b');
my $v = $w.assuming(c => 'c');
is $v(a => 'x'), 'ax bb cc', 'can curry on an already curried sub';
is $w(a => 'x', c => 'd'), 'ax bb cd', '... and the old one still works';

I just added support to the Parrot Compiler Toolkit for generating exception handlers. The only language I've patched to use this so far is Perl 6.

For example, this works:

do {
    say "foo";
    die "here is a failure";
    say "baz";
    CATCH {
        say "bar" if $_<message> ~~ /failure/;
        $_<resume>();
    }
}

And produces the output:

[sweeks@kweh]$ perl6 ehtest.pl
foo
bar
baz
[sweeks@kewh]$

Any Parrot language can now add support for exception handlers by adding a PAST::Control node to the 'handlers' attribute of a PAST::Stmts or PAST::Block node.

Here's the patch to Rakudo. Pretty small.

After another minor supporting change to Parrot, we'll have CONTROL blocks, and soon after we'll start supporting all of the control exceptions (next/last/redo) in all the appropriate loops.

Contact me on IRC if you want help or need anything else to support this in your language.

Thanks to my employer, Guru Labs for supporting all my work on Parrot.

About this Archive

This page is an archive of entries from December 2008 listed from newest to oldest.

November 2008 is the previous archive.

January 2009 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Pages

OpenID accepted here Learn more about OpenID
Powered by Movable Type 4.32-en