Idioms

I’ve contrived to do a good bit of $work programming in Perl 6 over the last few weeks, and I’ve been forced to develop a few new (or at least, new to me) idioms in the process. In particular, here’s one I mentioned on #perl6:

sub length(@points) {
    [+] (1 ..^ +@points).map({distance(@points[$_], @points[$_ - 1])});
}

Frequently in geometry you have to do something like this, where you have an array of items, and must compare each item in the list to the next. Initially I floundered around with code that looked something like this:

sub length(@points) {
    for @points.keys -> $i {
        next if $i == 0;
        distance(@points[$_], @points[$_ - 1])
    }
}

(Yes, that version doesn’t actually sum the distances, but you get the idea.) This is essentially trying to translate C++ idioms to Perl 6. The version at the top of the page is clearly better, and I was pleased with myself for working it out.

That said, it occurs to me that it would probably be better to do something like this:

sub pair-with-next(Iterable $a-iterable) {
    my $ai = $a-iterable.iterator;
    my $previous = $ai.get;
    return if $previous ~~ EMPTY;
    gather loop {
        my $current = $ai.get;
        last if $current ~~ EMPTY;
        take $previous;
        take $current;
        $previous = $current;
    }
}

(WARNING: This is completely untested code!) With that defined, you’d just say something like

sub length(@points) {
    [+] pair-with-next(@points).map(-> $a, $b {distance($a, $b)});
}

That feels much cleaner to me than the first version, and has the advantage that it can work on iterators as well as Seq/Arrays.

2 Responses to “Idioms”

  1. Eevee Says:

    My Perl 6 is a little outdated, but couldn’t you just do:

    sub length(@points) {
    [+] (@points Z @points[1..*]).map: distance(*$_)
    }

    • colomon Says:

      Almost, I don’t think distance(*$_) will quite do it. But yes, your general point of using Z like that is dead on. That idiom doesn’t work in Rakudo at the moment, so it slipped my mind.

Leave a reply to Eevee Cancel reply