Sign In/My Account | View Cart  
advertisement


Listen Print

Perl 6 : Not Just For Damians
by Piers Cawley | Pages: 1, 2, 3, 4

All operators get 'proper' function names.

This one almost had me punching the air. It's brilliant. Especially if, like me, you're the kind of person who goes slinging function references around. (One of the things that I really like about Ruby is its heady mix of functional style higher order functions and hard core object orientation. It looks like Perl's getting this too.)

Again, time to make with the examples. Consider the following perl code from an Assertion package (this is in Perl 6, it's too hard to write clearly in Perl 5).

    &assert_with_comparator := {
        unless ($^comparator.($^a, $^b)) {
            throw Exception::FailedComparison :
                comparator => $^comparator,
                result     => $^a,
                target     => $^b
        }
    }
    &assert_string_equals := assert_with_comparator(&operator:eq);
    &assert_num_equals    := assert_with_comparator(&operator:==);
    &assert_greater_than  := assert_with_comparator(&operator:>);

That's full strength Perl 6 that is, complete with currying, operators as functions, := binding, : used to disambiguate indirect object syntax, the whole nine yards. And it is still obviously a Perl program. The intent of the code is clear, even without comments, and it took very little time to write. Of course, I am assuming an Exception class, but we've already got that in Perl 5; take a look at the lovely Error.pm.

I'm not going to rewrite assert_with_comparator, but just look at the Perl 5 version of the last line of that example:

    *Assert::assert_greater_than =
        $assert_with_comparator->(sub { $_[0] > $_[1] });

Don't try and tell me that the intent is clearer in Perl 5 than in Perl 6, because I'll be forced to laugh at you.

binary and unary '.'

I confess that I'm still not sure I see where binary '.' is a win over '->', especially given that Larry has mandated that most of the time you won't even need it.

Unary '.' is looking really cool. If I read the Apocalypse right, this means that, instead of writing object methods like:

    sub method {
        my $self = shift;
        ...
        $self->{attribute} = $self->other_method(...);
        ...
    }

We can write:

    sub method {
        ...
        $.attribute = .other_method(...);
        ...
    }

Which is, once more clean, clear and perl like. This is the kind of notation I want Right Now. And, frankly, it'd just look silly if you replaced those '.'s with '->' (and should one parse $->attribute as an instance variable accessor, or as $- > attribute). Okay, I'm convinced. Replace '->' with '.' already.

Explicit stringification and numification operators

Again, these have got to be good magic, especially with the NaN stuff (though that's been the cause of some serious debate on perl6-language and may not be the eventual name). In at least one of the modules I'm involved in writing and maintaining, this would have been so useful:

    # geq: Generic equals
    sub operator:geq is prec(\&operator:eq($$)) ($expected, $got)
    {
        # Use numericness of $expected to determine which test to use
        if ( +$expected eq 'NaN') { return $expected eq $got }
        else                      { return $expected == $got }
    }
    sub assert_equals ($expected, $got; $comment)
    {
        $comment //= "Expected $expected, got $got";
        $expected geq $got or die $comment;
    }

Hey! That looks just like Perl! (Except that, to do the same thing in Perl 5, you have to jump through some splendidly non-obvious hoops. Trust me, I've done that.)

:=

This one had me scratching my head as I read the Apocalypse. On reading the Exegesis, things become a good deal clearer. := looks like it's going to be an easy way to export symbols from a module, now that typeglobs have gone away:

    package Foo;
    sub import ($class, @args) {
        # This is an example, ignore the args
        &{"${class}::foo"} := &Foo::foo;
    }

Of course, this isn't the only place where := will be used. Thankfully we'll be able to use it almost everywhere without having to remember all the caveats that used to surround assigning to typeglobs. Here's another example in Perl 6 of something that would be impossible in Perl 5:

    $Sunnydale{ScoobyGang}{Willow}{Traits} = [qw/cute geeky/];
    # Oooh Seasons 4 and 5 happened and I want
    # to use a trait object now
    $traits := $Sunnydale{ScoobyGang}{Willow}{Traits};
    $traits = new TraitCollection: qw/sexy witch lesbian geek/;

Nothing special there you say. Well, yes, but let's take a look at

    print $Sunnydale{ScoobyGang}{Willow}{Traits}
    # sexy witch lesbian geek
    # Or however a TraitCollection stringifies.

You can almost do this in Perl 5, but only if you continue to use an array:

    local *traits = $Sunnydale{ScoobyGang}{Willow}{Traits};
    @traits = qw/sexy witch lesbian geek/;

If you want to switch to using a TraitCollection, you'll have to go back and use the full specifier.

I think this is another of those bits of syntax that I'd like now, please.

Binary :

This is going to make life so much easier for the parser if nothing else. Right now, indirect object syntax can be very useful. However, if you've ever tried to use it in anger, well, you've ended up using it in anger because there are some subtle gotchas that will catch you out. Binary : lets us disambiguate many of these cases and helps to reclaim indirect object syntax as a useful way of working.

And so on... What's not to like? The sugar is sweet, the consistency is just right, and the old annoyances are going away.

Pages: 1, 2, 3, 4

Next Pagearrow